441 lines
9.4 KiB
C++
441 lines
9.4 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-2018 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 "foundation/PxAssert.h"
|
|
#include "RawLoader.h"
|
|
#include "PxTkFile.h"
|
|
|
|
typedef ::FILE File;
|
|
|
|
using namespace physx;
|
|
|
|
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;
|
|
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);
|
|
|
|
PxU32* pixels = NULL;
|
|
PxU8 r, g, b, a;
|
|
if (read8(fp))
|
|
{
|
|
data.mWidth = read32(fp);
|
|
data.mHeight = read32(fp);
|
|
data.mHasAlpha = read8(fp) != 0;
|
|
const PxU32 nbPixels = data.mWidth*data.mHeight;
|
|
pixels = new PxU32[nbPixels];
|
|
data.mPixels = pixels;
|
|
for (PxU32 i = 0; i<nbPixels; i++)
|
|
{
|
|
r = read8(fp);
|
|
g = read8(fp);
|
|
b = read8(fp);
|
|
|
|
if (data.mHasAlpha)
|
|
a = read8(fp);
|
|
else
|
|
a = 0xff;
|
|
|
|
//b, g, r, a
|
|
pixels[i] = b << 24 | g << 16 | r << 8 | a;
|
|
/*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);
|
|
delete[] 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);
|
|
|
|
PxVec3* tmpVerts = new PxVec3[data.mNbVerts];
|
|
PxVec3* tmpNormals = new PxVec3[data.mNbVerts];
|
|
PxVec3* 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 = new PxVec3[data.mNbVerts];
|
|
data.mVertexColors = tmpColors;
|
|
readVertexColors(fp, tmpColors, data.mNbVerts);
|
|
}
|
|
|
|
if (hasUVs)
|
|
{
|
|
tmpUVs = new PxReal[(sizeof(PxReal)*data.mNbVerts * 2)];
|
|
data.mUVs = tmpUVs;
|
|
readUVs(fp, tmpUVs, data.mNbVerts);
|
|
}
|
|
|
|
PxU32* tmpIndices = new PxU32[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)
|
|
{
|
|
delete[] tmpIndices;
|
|
delete[] tmpUVs;
|
|
delete[] tmpColors;
|
|
delete[] tmpNormals;
|
|
delete[] tmpVerts;
|
|
/*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);
|
|
|
|
delete[] tmpIndices;
|
|
delete[] tmpUVs;
|
|
delete[] tmpColors;
|
|
delete[] tmpNormals;
|
|
delete[] tmpVerts;
|
|
|
|
/* 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);
|
|
PxVec3* tmp = new PxVec3[data.mNbVerts];
|
|
data.mVerts = tmp;
|
|
readVertices(fp, tmp, data.mNbVerts, scale);
|
|
|
|
cb.newShape(data);
|
|
|
|
delete[] tmp;
|
|
}
|
|
|
|
// Helpers
|
|
for (PxU32 i = 0; i<nbHelpers; i++)
|
|
{
|
|
RAWHelper data;
|
|
|
|
readName(fp, objectName);
|
|
data.mName = objectName;
|
|
data.mTransform = readTransform(fp, scale);
|
|
}
|
|
return true;
|
|
}
|