416 lines
9.2 KiB
C++
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;
|
|
}
|