Files
PhysX4.1/physx/samples/samplebase/RawLoader.cpp
2025-11-28 23:13:44 +05:30

416 lines
9.2 KiB
C++

//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
// PT: this file is a loader for "raw" binary files. It should NOT create SDK objects directly.
#include <stdio.h>
#include "foundation/PxPreprocessor.h"
#include "RawLoader.h"
#include "RendererColor.h"
#include "RendererMemoryMacros.h"
#include "SampleAllocatorSDKClasses.h"
#include "PxTkFile.h"
using namespace SampleRenderer;
RAWObject::RAWObject() : mName(NULL)
{
mTransform = PxTransform(PxIdentity);
}
RAWTexture::RAWTexture() :
mID (0xffffffff),
mWidth (0),
mHeight (0),
mHasAlpha (false),
mPixels (NULL)
{
}
RAWMesh::RAWMesh() :
mNbVerts (0),
mNbFaces (0),
mMaterialID (0xffffffff),
mVerts (NULL),
mVertexNormals (NULL),
mVertexColors (NULL),
mUVs (NULL),
mIndices (NULL)
{
}
RAWShape::RAWShape() :
mNbVerts (0),
mVerts (NULL)
{
}
RAWHelper::RAWHelper()
{
}
RAWMaterial::RAWMaterial() :
mID (0xffffffff),
mDiffuseID (0xffffffff),
mOpacity (1.0f),
mDoubleSided (false)
{
mAmbientColor = PxVec3(0);
mDiffuseColor = PxVec3(0);
mSpecularColor = PxVec3(0);
}
#if PX_INTEL_FAMILY
static const bool gFlip = false;
#elif PX_PPC
static const bool gFlip = true;
#elif PX_ARM_FAMILY
static const bool gFlip = false;
#else
#error Unknown platform!
#endif
PX_INLINE void Flip(PxU32& v)
{
PxU8* b = (PxU8*)&v;
PxU8 temp = b[0];
b[0] = b[3];
b[3] = temp;
temp = b[1];
b[1] = b[2];
b[2] = temp;
}
PX_INLINE void Flip(PxI32& v)
{
Flip((PxU32&)v);
}
PX_INLINE void Flip(PxF32& v)
{
Flip((PxU32&)v);
}
static PxU8 read8(File* fp)
{
PxU8 data;
size_t numRead = fread(&data, 1, 1, fp);
if(numRead != 1) { return 0; }
return data;
}
static PxU32 read32(File* fp)
{
PxU32 data;
size_t numRead = fread(&data, 1, 4, fp);
if(numRead != 4) { return 0; }
if(gFlip)
Flip(data);
return data;
}
static PxF32 readFloat(File* fp)
{
PxF32 data;
size_t numRead = fread(&data, 1, 4, fp);
if(numRead != 4) { return 0; }
if(gFlip)
Flip(data);
return data;
}
static PxTransform readTransform(File* fp, PxReal scale)
{
PxTransform tr;
tr.p.x = scale * readFloat(fp);
tr.p.y = scale * readFloat(fp);
tr.p.z = scale * readFloat(fp);
tr.q.x = readFloat(fp);
tr.q.y = readFloat(fp);
tr.q.z = readFloat(fp);
tr.q.w = readFloat(fp);
PX_ASSERT(tr.isValid());
return tr;
}
static void readVertexArray(File* fp, PxVec3* verts, PxU32 nbVerts)
{
const size_t size = 4*3*nbVerts;
size_t numRead = fread(verts, 1, size, fp);
if(numRead != size) { return; }
if(gFlip)
{
for(PxU32 j=0;j<nbVerts;j++)
{
Flip(verts[j].x);
Flip(verts[j].y);
Flip(verts[j].z);
}
}
}
static void readUVs(File* fp, PxReal* uvs, PxU32 nbVerts)
{
const size_t size = 4*2*nbVerts;
size_t numRead = fread(uvs, 1, size, fp);
if(numRead != size) { return; }
if(gFlip)
{
for(PxU32 j=0;j<nbVerts*2;j++)
Flip(uvs[j]);
}
}
static void readVertices(File* fp, PxVec3* verts, PxU32 nbVerts, PxReal scale)
{
readVertexArray(fp, verts, nbVerts);
for(PxU32 j=0;j<nbVerts;j++)
verts[j] *= scale;
}
static void readNormals(File* fp, PxVec3* verts, PxU32 nbVerts)
{
readVertexArray(fp, verts, nbVerts);
}
static void readVertexColors(File* fp, PxVec3* colors, PxU32 nbVerts)
{
readVertexArray(fp, colors, nbVerts);
}
static void readName(File* fp, char* objectName)
{
PxU32 offset=0;
char c;
do
{
size_t numRead = fread(&c, 1, 1, fp);
if(numRead != 1) { c = '\0';}
objectName[offset++] = c;
}while(c);
objectName[offset]=0;
}
bool loadRAWfile(const char* filename, RAWImportCallback& cb, PxReal scale)
{
File* fp = NULL;
PxToolkit::fopen_s(&fp, filename, "rb");
if(!fp)
return false;
// General info
const PxU32 tag = read32(fp);
const PxU32 generalVersion = read32(fp);
const PxU32 nbMaterials = read32(fp);
const PxU32 nbTextures = read32(fp);
const PxU32 nbMeshes = read32(fp);
const PxU32 nbShapes = read32(fp);
const PxU32 nbHelpers = read32(fp);
(void)tag;
(void)generalVersion;
char objectName[512];
// Textures
for(PxU32 i=0;i<nbTextures;i++)
{
RAWTexture data;
readName(fp, objectName);
data.mName = objectName;
data.mTransform = PxTransform(PxIdentity); // PT: texture transform not supported yet
data.mID = read32(fp);
RendererColorAlloc* pixels = NULL;
if(read8(fp))
{
data.mWidth = read32(fp);
data.mHeight = read32(fp);
data.mHasAlpha = read8(fp)!=0;
const PxU32 nbPixels = data.mWidth*data.mHeight;
pixels = SAMPLE_NEW(RendererColorAlloc)[nbPixels];
data.mPixels = pixels;
for(PxU32 i=0;i<nbPixels;i++)
{
pixels[i].r = read8(fp);
pixels[i].g = read8(fp);
pixels[i].b = read8(fp);
if(data.mHasAlpha)
pixels[i].a = read8(fp);
else
pixels[i].a = 0xff;
}
}
else
{
data.mWidth = 0;
data.mHeight = 0;
data.mHasAlpha = false;
data.mPixels = NULL;
}
cb.newTexture(data);
DELETEARRAY(pixels);
}
// Materials
for(PxU32 i=0;i<nbMaterials;i++)
{
RAWMaterial data;
data.mID = read32(fp);
data.mDiffuseID = read32(fp);
data.mOpacity = readFloat(fp);
data.mDoubleSided = read32(fp)!=0;
data.mAmbientColor.x = readFloat(fp);
data.mAmbientColor.y = readFloat(fp);
data.mAmbientColor.z = readFloat(fp);
data.mDiffuseColor.x = readFloat(fp);
data.mDiffuseColor.y = readFloat(fp);
data.mDiffuseColor.z = readFloat(fp);
data.mSpecularColor.x = readFloat(fp);
data.mSpecularColor.y = readFloat(fp);
data.mSpecularColor.z = readFloat(fp);
cb.newMaterial(data);
}
// Meshes
for(PxU32 i=0;i<nbMeshes;i++)
{
RAWMesh data;
readName(fp, objectName);
data.mName = objectName;
data.mTransform = readTransform(fp, scale);
//
data.mNbVerts = read32(fp);
data.mNbFaces = read32(fp);
const PxU32 hasVertexColors = read32(fp);
const PxU32 hasUVs = read32(fp);
data.mMaterialID = read32(fp);
PxVec3Alloc* tmpVerts = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];
PxVec3Alloc* tmpNormals = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];
PxVec3Alloc* tmpColors = NULL;
PxReal* tmpUVs = NULL;
data.mVerts = tmpVerts;
data.mVertexNormals = tmpNormals;
data.mVertexColors = NULL;
data.mUVs = NULL;
readVertices(fp, tmpVerts, data.mNbVerts, scale);
readNormals(fp, tmpNormals, data.mNbVerts);
if(hasVertexColors)
{
tmpColors = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];
data.mVertexColors = tmpColors;
readVertexColors(fp, tmpColors, data.mNbVerts);
}
if(hasUVs)
{
tmpUVs = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*data.mNbVerts*2);
data.mUVs = tmpUVs;
readUVs(fp, tmpUVs, data.mNbVerts);
}
PxU32* tmpIndices = (PxU32*)SAMPLE_ALLOC(sizeof(PxU32)*data.mNbFaces*3);
data.mIndices = tmpIndices;
const size_t size = 4*3*data.mNbFaces;
size_t numRead = fread(tmpIndices, 1, size, fp);
if(numRead != size)
{
SAMPLE_FREE(tmpIndices);
SAMPLE_FREE(tmpUVs);
DELETEARRAY(tmpColors);
DELETEARRAY(tmpNormals);
DELETEARRAY(tmpVerts);
return false;
}
if(gFlip)
{
for(PxU32 j=0;j<data.mNbFaces*3;j++)
{
Flip(tmpIndices[j]);
}
}
cb.newMesh(data);
SAMPLE_FREE(tmpIndices);
SAMPLE_FREE(tmpUVs);
DELETEARRAY(tmpColors);
DELETEARRAY(tmpNormals);
DELETEARRAY(tmpVerts);
}
// Shapes
for(PxU32 i=0;i<nbShapes;i++)
{
RAWShape data;
readName(fp, objectName);
data.mName = objectName;
data.mTransform = readTransform(fp, scale);
//
data.mNbVerts = read32(fp);
PxVec3Alloc* tmp = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];
data.mVerts = tmp;
readVertices(fp, tmp, data.mNbVerts, scale);
cb.newShape(data);
DELETEARRAY(tmp);
}
// Helpers
for(PxU32 i=0;i<nbHelpers;i++)
{
RAWHelper data;
readName(fp, objectName);
data.mName = objectName;
data.mTransform = readTransform(fp, scale);
}
return true;
}