Commit 154b5d91 authored by hybrid's avatar hybrid

Merged from 1.4 branch revisions 1155:1172

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1173 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 6436ded4
...@@ -120,17 +120,18 @@ namespace scene ...@@ -120,17 +120,18 @@ namespace scene
virtual bool isInputReceiverEnabled() const = 0; virtual bool isInputReceiverEnabled() const = 0;
//! Returns if a camera is orthogonal. //! Returns if a camera is orthogonal.
/** This setting does not change anything of the view or projection matrix. However
it influences how collision detection and picking is done with this camera. */
virtual bool isOrthogonal() const virtual bool isOrthogonal() const
{ {
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return IsOrthogonal; return IsOrthogonal;
} }
//! Sets if this camera should return if it is orthogonal. //! Sets if this camera should return that it is orthogonal.
/** This setting does not change anything of the view or projection matrix. However /** This setting does not change anything of the view or
it influences how collision detection and picking is done with this camera. */ projection matrix. However, the kind of camera
influences how collision detection and picking is done
and thus can be useful to query.
*/
void setIsOrthogonal( bool orthogonal ) void setIsOrthogonal( bool orthogonal )
{ {
IsOrthogonal = orthogonal; IsOrthogonal = orthogonal;
......
...@@ -77,6 +77,11 @@ struct S3DVertex ...@@ -77,6 +77,11 @@ struct S3DVertex
(Color != other.Color) || (TCoords != other.TCoords)); (Color != other.Color) || (TCoords != other.TCoords));
} }
bool operator<(const S3DVertex& other) const
{
return ((Pos < other.Pos) || ((Pos == other.Pos) && (Normal < other.Normal)) || ((Pos == other.Pos) && (Normal == other.Normal) && (Color < other.Color)) || ((Pos == other.Pos) && (Normal == other.Normal) && (Color == other.Color) && (TCoords < other.TCoords)));
}
E_VERTEX_TYPE getType() const E_VERTEX_TYPE getType() const
{ {
return EVT_STANDARD; return EVT_STANDARD;
...@@ -140,6 +145,11 @@ struct S3DVertex2TCoords : public S3DVertex ...@@ -140,6 +145,11 @@ struct S3DVertex2TCoords : public S3DVertex
(TCoords2 != other.TCoords2)); (TCoords2 != other.TCoords2));
} }
bool operator<(const S3DVertex2TCoords& other) const
{
return ((static_cast<S3DVertex>(*this) < other) || ((static_cast<S3DVertex>(*this) == other) && (TCoords2 < other.TCoords2)));
}
E_VERTEX_TYPE getType() const E_VERTEX_TYPE getType() const
{ {
return EVT_2TCOORDS; return EVT_2TCOORDS;
...@@ -192,6 +202,11 @@ struct S3DVertexTangents : public S3DVertex ...@@ -192,6 +202,11 @@ struct S3DVertexTangents : public S3DVertex
(Binormal != other.Binormal)); (Binormal != other.Binormal));
} }
bool operator<(const S3DVertexTangents& other) const
{
return ((static_cast<S3DVertex>(*this) < other) || ((static_cast<S3DVertex>(*this) == other) && (Tangent < other.Tangent)) || ((static_cast<S3DVertex>(*this) == other) && (Tangent == other.Tangent) && (Binormal < other.Binormal)));
}
E_VERTEX_TYPE getType() const E_VERTEX_TYPE getType() const
{ {
return EVT_TANGENTS; return EVT_TANGENTS;
......
...@@ -285,6 +285,10 @@ namespace video ...@@ -285,6 +285,10 @@ namespace video
//! \return Returns true if the colors are different, and false if they are the same. //! \return Returns true if the colors are different, and false if they are the same.
inline bool operator!=(const SColor& other) const { return other.color != color; } inline bool operator!=(const SColor& other) const { return other.color != color; }
//! comparison operator
//! \return Returns true if this color is smaller than the other one
inline bool operator<(const SColor& other) const { return (color < other.color); }
//! Adds two colors //! Adds two colors
inline SColor operator+(const SColor& other) const inline SColor operator+(const SColor& other) const
{ {
......
...@@ -19,8 +19,8 @@ namespace core ...@@ -19,8 +19,8 @@ namespace core
#define DEBUG_CLIENTBLOCK new #define DEBUG_CLIENTBLOCK new
#endif #endif
//! Very simple allocator implementation, containers using it are able to //! Very simple allocator implementation, containers using it can
//! be used it across dll boundaries //! be used across dll boundaries
template<typename T> template<typename T>
class irrAllocator class irrAllocator
{ {
......
...@@ -102,7 +102,7 @@ namespace core ...@@ -102,7 +102,7 @@ namespace core
template<class T> template<class T>
inline T lerp(const T& a, const T& b, const f32 t) inline T lerp(const T& a, const T& b, const f32 t)
{ {
return (a*(1.f-t)) + (b*t); return (T)(a*(1.f-t)) + (b*t);
} }
//! clamps a value between low and high //! clamps a value between low and high
......
...@@ -104,6 +104,7 @@ namespace core ...@@ -104,6 +104,7 @@ namespace core
const f32 ac_bb = (a*c)-(b*b); const f32 ac_bb = (a*c)-(b*b);
f32 z = x+y-ac_bb; f32 z = x+y-ac_bb;
// return sign(z) && !(sign(x)||sign(y))
return (( (IR(z)) & ~((IR(x))|(IR(y))) ) & 0x80000000)!=0; return (( (IR(z)) & ~((IR(x))|(IR(y))) ) & 0x80000000)!=0;
} }
......
...@@ -56,6 +56,9 @@ namespace scene ...@@ -56,6 +56,9 @@ namespace scene
const core::stringc scaleNodeName = "scale"; const core::stringc scaleNodeName = "scale";
const core::stringc translateNodeName = "translate"; const core::stringc translateNodeName = "translate";
const core::stringc skewNodeName = "skew"; const core::stringc skewNodeName = "skew";
const core::stringc bboxNodeName = "boundingbox";
const core::stringc minNodeName = "min";
const core::stringc maxNodeName = "max";
const core::stringc instanceNodeName = "instance"; const core::stringc instanceNodeName = "instance";
const core::stringc paramTagName = "param"; const core::stringc paramTagName = "param";
...@@ -389,14 +392,50 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader) ...@@ -389,14 +392,50 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
// read the scene // read the scene
core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
scene::IDummyTransformationSceneNode* node = 0;
while(reader->read()) while(reader->read())
if (reader->getNodeType() == io::EXN_ELEMENT) if (reader->getNodeType() == io::EXN_ELEMENT)
{ {
if (lookatNodeName == reader->getNodeName())
transform *= readLookAtNode(reader);
else
if (matrixNodeName == reader->getNodeName())
transform *= readMatrixNode(reader);
else
if (perspectiveNodeName == reader->getNodeName())
transform *= readPerspectiveNode(reader);
else
if (rotateNodeName == reader->getNodeName())
transform *= readRotateNode(reader);
else
if (scaleNodeName == reader->getNodeName())
transform *= readScaleNode(reader);
else
if (translateNodeName == reader->getNodeName())
transform *= readTranslateNode(reader);
else
if (skewNodeName == reader->getNodeName())
transform *= readSkewNode(reader);
else
if (bboxNodeName == reader->getNodeName())
readBboxNode(reader, bbox);
else
if (nodeSectionName == reader->getNodeName()) if (nodeSectionName == reader->getNodeName())
readNodeSection(reader, SceneManager->getRootSceneNode()); {
// create dummy node if there is none yet.
if (!node)
node = SceneManager->addDummyTransformationSceneNode(SceneManager->getRootSceneNode());
readNodeSection(reader, node);
}
else else
skipSection(reader, true); // ignore all other sections skipSection(reader, true); // ignore all other sections
} }
if (node)
node->getRelativeTransformationMatrix() = transform;
} }
...@@ -426,11 +465,13 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce ...@@ -426,11 +465,13 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
core::stringc name = reader->getAttributeValue("name"); // name of the node core::stringc name = reader->getAttributeValue("name"); // name of the node
core::matrix4 transform; // transformation of this node core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
scene::ISceneNode* node = 0; // instance scene::ISceneNode* node = 0; // instance
// read the node // read the node
while(reader->read()) while(reader->read())
{
if (reader->getNodeType() == io::EXN_ELEMENT) if (reader->getNodeType() == io::EXN_ELEMENT)
{ {
if (lookatNodeName == reader->getNodeName()) if (lookatNodeName == reader->getNodeName())
...@@ -454,6 +495,9 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce ...@@ -454,6 +495,9 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
if (skewNodeName == reader->getNodeName()) if (skewNodeName == reader->getNodeName())
transform *= readSkewNode(reader); transform *= readSkewNode(reader);
else else
if (bboxNodeName == reader->getNodeName())
readBboxNode(reader, bbox);
else
if (instanceNodeName == reader->getNodeName()) if (instanceNodeName == reader->getNodeName())
{ {
scene::ISceneNode* newnode = 0; scene::ISceneNode* newnode = 0;
...@@ -497,17 +541,14 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce ...@@ -497,17 +541,14 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
if (nodeSectionName == reader->getNodeName()) if (nodeSectionName == reader->getNodeName())
break; break;
} }
}
if (node) if (node)
{ {
// TODO: set transformation correctly into node. // set transformation correctly into node.
// currently this isn't done correctly. Need to get transformation, node->setPosition(transform.getTranslation());
// rotation and scale from the matrix. node->setRotation(transform.getRotationDegrees());
const core::vector3df& trans = transform.getTranslation(); node->setScale(transform.getScale());
const core::vector3df& rot = transform.getRotationDegrees();
node->setPosition(trans);
node->setRotation(rot);
node->updateAbsolutePosition(); node->updateAbsolutePosition();
node->setName(name.c_str()); node->setName(name.c_str());
...@@ -537,6 +578,7 @@ core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader) ...@@ -537,6 +578,7 @@ core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader)
return mat; return mat;
} }
//! reads a <skew> element and its content and creates a matrix from it //! reads a <skew> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader) core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader)
{ {
...@@ -548,16 +590,85 @@ core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader) ...@@ -548,16 +590,85 @@ core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader)
if (reader->isEmptyElement()) if (reader->isEmptyElement())
return mat; return mat;
f32 floats[7]; f32 floats[7]; // angle rotation-axis translation-axis
readFloatsInsideElement(reader, floats, 7); readFloatsInsideElement(reader, floats, 7);
// TODO: build skew matrix from these 7 floats // build skew matrix from these 7 floats
core::quaternion q;
q.fromAngleAxis(floats[0]*core::DEGTORAD, core::vector3df(floats[1], floats[2], floats[3]));
q.getMatrix(mat);
os::Printer::log("COLLADA loader warning: <skew> not implemented yet.", ELL_WARNING); if (floats[4]==1.f) // along x-axis
{
mat[4]=0.f;
mat[6]=0.f;
mat[8]=0.f;
mat[9]=0.f;
}
else
if (floats[5]==1.f) // along y-axis
{
mat[1]=0.f;
mat[2]=0.f;
mat[8]=0.f;
mat[9]=0.f;
}
else
if (floats[6]==1.f) // along z-axis
{
mat[1]=0.f;
mat[2]=0.f;
mat[4]=0.f;
mat[6]=0.f;
}
return mat; return mat;
} }
//! reads a <boundingbox> element and its content and stores it in bbox
void CColladaFileLoader::readBboxNode(io::IXMLReaderUTF8* reader,
core::aabbox3df& bbox)
{
#ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA reading boundingbox node");
#endif
bbox.reset(core::aabbox3df());
if (reader->isEmptyElement())
return;
f32 floats[3];
while(reader->read())
{
if (reader->getNodeType() == io::EXN_ELEMENT)
{
if (minNodeName == reader->getNodeName())
{
readFloatsInsideElement(reader, floats, 3);
bbox.MinEdge.set(floats[0], floats[1], floats[2]);
}
else
if (maxNodeName == reader->getNodeName())
{
readFloatsInsideElement(reader, floats, 3);
bbox.MaxEdge.set(floats[0], floats[1], floats[2]);
}
else
skipSection(reader, true); // ignore all other sections
}
else
if (reader->getNodeType() == io::EXN_ELEMENT_END)
{
if (bboxNodeName == reader->getNodeName())
break;
}
}
}
//! reads a <matrix> element and its content and creates a matrix from it //! reads a <matrix> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader) core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
{ {
...@@ -574,6 +685,7 @@ core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader) ...@@ -574,6 +685,7 @@ core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
return mat; return mat;
} }
//! reads a <perspective> element and its content and creates a matrix from it //! reads a <perspective> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader) core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader)
{ {
...@@ -595,6 +707,7 @@ core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader ...@@ -595,6 +707,7 @@ core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader
return mat; return mat;
} }
//! reads a <rotate> element and its content and creates a matrix from it //! reads a <rotate> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader) core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
{ {
...@@ -609,10 +722,12 @@ core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader) ...@@ -609,10 +722,12 @@ core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
f32 floats[4]; f32 floats[4];
readFloatsInsideElement(reader, floats, 4); readFloatsInsideElement(reader, floats, 4);
core::quaternion q(floats[0], floats[1], floats[2], floats[3]); core::quaternion q;
q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2]));
return q.getMatrix(); return q.getMatrix();
} }
//! reads a <scale> element and its content and creates a matrix from it //! reads a <scale> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readScaleNode(io::IXMLReaderUTF8* reader) core::matrix4 CColladaFileLoader::readScaleNode(io::IXMLReaderUTF8* reader)
{ {
...@@ -652,6 +767,7 @@ core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader) ...@@ -652,6 +767,7 @@ core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader)
return mat; return mat;
} }
//! reads a <instance> node and creates a scene node from it //! reads a <instance> node and creates a scene node from it
void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent,
scene::ISceneNode** outNode) scene::ISceneNode** outNode)
......
...@@ -199,6 +199,9 @@ private: ...@@ -199,6 +199,9 @@ private:
//! reads a <skew> element and its content and creates a matrix from it //! reads a <skew> element and its content and creates a matrix from it
core::matrix4 readSkewNode(io::IXMLReaderUTF8* reader); core::matrix4 readSkewNode(io::IXMLReaderUTF8* reader);
//! reads a <boundingbox> element and its content and stores it in bbox
void readBboxNode(io::IXMLReaderUTF8* reader, core::aabbox3df& bbox);
//! reads a <scale> element and its content and creates a matrix from it //! reads a <scale> element and its content and creates a matrix from it
core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader); core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "IReadFile.h" #include "IReadFile.h"
#include "fast_atof.h" #include "fast_atof.h"
#include "coreutil.h" #include "coreutil.h"
#include "irrMap.h"
namespace irr namespace irr
{ {
...@@ -70,9 +71,10 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -70,9 +71,10 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
core::array<core::vector2df> textureCoordBuffer; core::array<core::vector2df> textureCoordBuffer;
core::array<core::vector3df> normalsBuffer; core::array<core::vector3df> normalsBuffer;
SObjMtl * currMtl = new SObjMtl(); SObjMtl * currMtl = new SObjMtl();
currMtl->name=""; currMtl->Name="";
materials.push_back(currMtl); materials.push_back(currMtl);
u32 smoothingGroup=0; u32 smoothingGroup=0;
core::map<video::S3DVertex, int> vertMap;
// ******************************************************************** // ********************************************************************
// Patch to locate the file in the same folder as the .obj. // Patch to locate the file in the same folder as the .obj.
...@@ -93,21 +95,21 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -93,21 +95,21 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
// end of mtl folder patch // end of mtl folder patch
// ******************************************************************** // ********************************************************************
c8* pBuf = new c8[filesize]; c8* buf = new c8[filesize];
memset(pBuf, 0, filesize); memset(buf, 0, filesize);
file->read((void*)pBuf, filesize); file->read((void*)buf, filesize);
const c8* const pBufEnd = pBuf+filesize; const c8* const bufEnd = buf+filesize;
// Process obj information // Process obj information
const c8* bufPtr = pBuf; const c8* bufPtr = buf;
while(bufPtr != pBufEnd) while(bufPtr != bufEnd)
{ {
switch(bufPtr[0]) switch(bufPtr[0])
{ {
case 'm': // mtllib (material) case 'm': // mtllib (material)
{ {
c8 name[WORD_BUFFER_LENGTH]; c8 name[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(name, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(name, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
readMTL(name, obj_relpath); readMTL(name, obj_relpath);
} }
break; break;
...@@ -118,7 +120,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -118,7 +120,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
case ' ': // vertex case ' ': // vertex
{ {
core::vector3df vec; core::vector3df vec;
bufPtr = readVec3(bufPtr, vec, pBufEnd); bufPtr = readVec3(bufPtr, vec, bufEnd);
vertexBuffer.push_back(vec); vertexBuffer.push_back(vec);
} }
break; break;
...@@ -126,7 +128,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -126,7 +128,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
case 'n': // normal case 'n': // normal
{ {
core::vector3df vec; core::vector3df vec;
bufPtr = readVec3(bufPtr, vec, pBufEnd); bufPtr = readVec3(bufPtr, vec, bufEnd);
normalsBuffer.push_back(vec); normalsBuffer.push_back(vec);
} }
break; break;
...@@ -134,7 +136,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -134,7 +136,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
case 't': // texcoord case 't': // texcoord
{ {
core::vector2df vec; core::vector2df vec;
bufPtr = readVec2(bufPtr, vec, pBufEnd); bufPtr = readVec2(bufPtr, vec, bufEnd);
textureCoordBuffer.push_back(vec); textureCoordBuffer.push_back(vec);
} }
break; break;
...@@ -149,7 +151,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -149,7 +151,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
case 's': // smoothing can be a group or off (equiv. to 0) case 's': // smoothing can be a group or off (equiv. to 0)
{ {
c8 smooth[WORD_BUFFER_LENGTH]; c8 smooth[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(smooth, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(smooth, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (core::stringc("off")==smooth) if (core::stringc("off")==smooth)
smoothingGroup=0; smoothingGroup=0;
else else
...@@ -161,12 +163,12 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -161,12 +163,12 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
// get name of material // get name of material
{ {
c8 matName[WORD_BUFFER_LENGTH]; c8 matName[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(matName, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(matName, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// retrieve the material // retrieve the material
SObjMtl *pUseMtl = findMtl(matName); SObjMtl *useMtl = findMtl(matName);
// only change material if we found it // only change material if we found it
if (pUseMtl) if (useMtl)
currMtl = pUseMtl; currMtl = useMtl;
} }
break; break;
...@@ -174,18 +176,18 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -174,18 +176,18 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
{ {
c8 vertexWord[WORD_BUFFER_LENGTH]; // for retrieving vertex data c8 vertexWord[WORD_BUFFER_LENGTH]; // for retrieving vertex data
video::S3DVertex v; video::S3DVertex v;
u32 currentVertexCount = currMtl->Meshbuffer->Vertices.size();
u32 facePointCount = 0; // number of vertices in this face
// Assign vertex color from currently active material's diffuse colour // Assign vertex color from currently active material's diffuse colour
if (currMtl) if (currMtl)
v.Color = currMtl->Meshbuffer->Material.DiffuseColor; v.Color = currMtl->Meshbuffer->Material.DiffuseColor;
// get all vertices data in this face (current line of obj file) // get all vertices data in this face (current line of obj file)
const core::stringc wordBuffer = copyLine(bufPtr, pBufEnd); const core::stringc wordBuffer = copyLine(bufPtr, bufEnd);
const c8* linePtr = wordBuffer.c_str(); const c8* linePtr = wordBuffer.c_str();
const c8* const endPtr = linePtr+wordBuffer.size(); const c8* const endPtr = linePtr+wordBuffer.size();
core::array<int> faceCorners;
faceCorners.reallocate(32); // should be large enough
// read in all vertices // read in all vertices
linePtr = goNextWord(linePtr, endPtr); linePtr = goNextWord(linePtr, endPtr);
while (0 != linePtr[0]) while (0 != linePtr[0])
...@@ -197,7 +199,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -197,7 +199,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
Idx[1] = Idx[2] = -1; Idx[1] = Idx[2] = -1;
// read in next vertex's data // read in next vertex's data
u32 wlength = copyWord(vertexWord, linePtr, WORD_BUFFER_LENGTH, pBufEnd); u32 wlength = copyWord(vertexWord, linePtr, WORD_BUFFER_LENGTH, bufEnd);
// this function will also convert obj's 1-based index to c++'s 0-based index // this function will also convert obj's 1-based index to c++'s 0-based index
retrieveVertexIndices(vertexWord, Idx, vertexWord+wlength+1, vertexBuffer.size(), textureCoordBuffer.size(), normalsBuffer.size()); retrieveVertexIndices(vertexWord, Idx, vertexWord+wlength+1, vertexBuffer.size(), textureCoordBuffer.size(), normalsBuffer.size());
v.Pos = vertexBuffer[Idx[0]]; v.Pos = vertexBuffer[Idx[0]];
...@@ -209,24 +211,36 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -209,24 +211,36 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
v.Normal = normalsBuffer[Idx[2]]; v.Normal = normalsBuffer[Idx[2]];
else else
v.Normal.set(0.0f,0.0f,0.0f); v.Normal.set(0.0f,0.0f,0.0f);
currMtl->Meshbuffer->Vertices.push_back(v);
++facePointCount; int vertLocation;
core::map<video::S3DVertex, int>::Node* n = vertMap.find(v);
if (n)
{
vertLocation = n->getValue();
}
else
{
currMtl->Meshbuffer->Vertices.push_back(v);
vertLocation = currMtl->Meshbuffer->Vertices.size() -1;
vertMap.insert(v, vertLocation);
}
faceCorners.push_back(vertLocation);
// go to next vertex // go to next vertex
linePtr = goNextWord(linePtr, endPtr); linePtr = goNextWord(linePtr, endPtr);
} }
// Add indices for first 3 vertices // triangulate the face
currMtl->Meshbuffer->Indices.push_back( currentVertexCount ); for ( u32 i = 1; i < faceCorners.size() - 1; ++i )
currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 1 ) + currentVertexCount );
currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 2 ) + currentVertexCount );
// Add indices for subsequent vertices
for ( u32 i = 0; i < facePointCount - 3; ++i )
{ {
currMtl->Meshbuffer->Indices.push_back( currentVertexCount ); // Add a triangle
currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 2 - i ) + currentVertexCount ); currMtl->Meshbuffer->Indices.push_back( faceCorners[i+1] );
currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 3 - i ) + currentVertexCount ); currMtl->Meshbuffer->Indices.push_back( faceCorners[i] );
currMtl->Meshbuffer->Indices.push_back( faceCorners[0] );
} }
faceCorners.set_used(0); // fast clear
faceCorners.reallocate(32);
} }
break; break;
...@@ -235,8 +249,8 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -235,8 +249,8 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
break; break;
} // end switch(bufPtr[0]) } // end switch(bufPtr[0])
// eat up rest of line // eat up rest of line
bufPtr = goNextLine(bufPtr, pBufEnd); bufPtr = goNextLine(bufPtr, bufEnd);
} // end while(bufPtr && (bufPtr-pBuf<filesize)) } // end while(bufPtr && (bufPtr-buf<filesize))
// Combine all the groups (meshbuffers) into the mesh // Combine all the groups (meshbuffers) into the mesh
for ( u32 m = 0; m < materials.size(); ++m ) for ( u32 m = 0; m < materials.size(); ++m )
...@@ -249,125 +263,125 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) ...@@ -249,125 +263,125 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
} }
// Create the Animated mesh if there's anything in the mesh // Create the Animated mesh if there's anything in the mesh
SAnimatedMesh* pAM = 0; SAnimatedMesh* animMesh = 0;
if ( 0 != mesh->getMeshBufferCount() ) if ( 0 != mesh->getMeshBufferCount() )
{ {
mesh->recalculateBoundingBox(); mesh->recalculateBoundingBox();
pAM = new SAnimatedMesh(); animMesh = new SAnimatedMesh();
pAM->Type = EAMT_OBJ; animMesh->Type = EAMT_OBJ;
pAM->addMesh(mesh); animMesh->addMesh(mesh);
pAM->recalculateBoundingBox(); animMesh->recalculateBoundingBox();
} }
// Clean up the allocate obj file contents // Clean up the allocate obj file contents
delete [] pBuf; delete [] buf;
// more cleaning up // more cleaning up
cleanUp(); cleanUp();
mesh->drop(); mesh->drop();
return pAM; return animMesh;
} }
void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath) void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
{ {
const u32 WORD_BUFFER_LENGTH = 512; const u32 WORD_BUFFER_LENGTH = 512;
io::IReadFile * pMtlReader; io::IReadFile * mtlReader;
if (FileSystem->existFile(pFileName)) if (FileSystem->existFile(fileName))
pMtlReader = FileSystem->createAndOpenFile(pFileName); mtlReader = FileSystem->createAndOpenFile(fileName);
else else
// try to read in the relative path, the .obj is loaded from // try to read in the relative path, the .obj is loaded from
pMtlReader = FileSystem->createAndOpenFile((relPath + pFileName).c_str()); mtlReader = FileSystem->createAndOpenFile((relPath + fileName).c_str());
if (!pMtlReader) // fail to open and read file if (!mtlReader) // fail to open and read file
return; return;
const long filesize = pMtlReader->getSize(); const long filesize = mtlReader->getSize();
if (!filesize) if (!filesize)
return; return;
c8* pBuf = new c8[filesize]; c8* buf = new c8[filesize];
pMtlReader->read((void*)pBuf, filesize); mtlReader->read((void*)buf, filesize);
const c8* pBufEnd = pBuf+filesize; const c8* bufEnd = buf+filesize;
SObjMtl* pCurrMaterial = 0; SObjMtl* currMaterial = 0;
const c8* bufPtr = pBuf; const c8* bufPtr = buf;
while(bufPtr != pBufEnd) while(bufPtr != bufEnd)
{ {
switch(*bufPtr) switch(*bufPtr)
{ {
case 'n': // newmtl case 'n': // newmtl
{ {
// if there's an existing material, store it first // if there's an existing material, store it first
if ( pCurrMaterial ) if ( currMaterial )
materials.push_back( pCurrMaterial ); materials.push_back( currMaterial );
// extract new material's name // extract new material's name
c8 mtlNameBuf[WORD_BUFFER_LENGTH]; c8 mtlNameBuf[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(mtlNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(mtlNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
pCurrMaterial = new SObjMtl; currMaterial = new SObjMtl;
pCurrMaterial->name = mtlNameBuf; currMaterial->Name = mtlNameBuf;
} }
break; break;
case 'i': // illum - illumination case 'i': // illum - illumination
if ( pCurrMaterial ) if ( currMaterial )
{ {
const u32 COLOR_BUFFER_LENGTH = 16; const u32 COLOR_BUFFER_LENGTH = 16;
c8 illumStr[COLOR_BUFFER_LENGTH]; c8 illumStr[COLOR_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(illumStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(illumStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
pCurrMaterial->illumination = (c8)atol(illumStr); currMaterial->Illumination = (c8)atol(illumStr);
} }
break; break;
case 'N': // Ns - shininess case 'N': // Ns - shininess
if ( pCurrMaterial ) if ( currMaterial )
{ {
const u32 COLOR_BUFFER_LENGTH = 16; const u32 COLOR_BUFFER_LENGTH = 16;
c8 nsStr[COLOR_BUFFER_LENGTH]; c8 nsStr[COLOR_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(nsStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(nsStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
f32 shininessValue = core::fast_atof(nsStr); f32 shininessValue = core::fast_atof(nsStr);
// wavefront shininess is from [0, 1000], so scale for OpenGL // wavefront shininess is from [0, 1000], so scale for OpenGL
shininessValue *= 0.128f; shininessValue *= 0.128f;
pCurrMaterial->Meshbuffer->Material.Shininess = shininessValue; currMaterial->Meshbuffer->Material.Shininess = shininessValue;
} }
break; break;
case 'K': case 'K':
if ( pCurrMaterial ) if ( currMaterial )
{ {
switch(bufPtr[1]) switch(bufPtr[1])
{ {
case 'd': // Kd = diffuse case 'd': // Kd = diffuse
{ {
bufPtr = readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.DiffuseColor, pBufEnd); bufPtr = readColor(bufPtr, currMaterial->Meshbuffer->Material.DiffuseColor, bufEnd);
} }
break; break;
case 's': // Ks = specular case 's': // Ks = specular
{ {
bufPtr = readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.SpecularColor, pBufEnd); bufPtr = readColor(bufPtr, currMaterial->Meshbuffer->Material.SpecularColor, bufEnd);
} }
break; break;
case 'a': // Ka = ambience case 'a': // Ka = ambience
{ {
bufPtr=readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.AmbientColor, pBufEnd); bufPtr=readColor(bufPtr, currMaterial->Meshbuffer->Material.AmbientColor, bufEnd);
} }
break; break;
case 'e': // Ke = emissive case 'e': // Ke = emissive
{ {
bufPtr=readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.EmissiveColor, pBufEnd); bufPtr=readColor(bufPtr, currMaterial->Meshbuffer->Material.EmissiveColor, bufEnd);
} }
break; break;
} // end switch(bufPtr[1]) } // end switch(bufPtr[1])
} // end case 'K': if ( 0 != pCurrMaterial )... } // end case 'K': if ( 0 != currMaterial )...
break; break;
case 'm': // texture maps case 'm': // texture maps
if (pCurrMaterial) if (currMaterial)
{ {
u8 type=0; // map_Kd - diffuse texture map u8 type=0; // map_Kd - diffuse texture map
if (!strncmp(bufPtr,"map_bump",8)) if (!strncmp(bufPtr,"map_bump",8))
...@@ -378,117 +392,117 @@ void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath) ...@@ -378,117 +392,117 @@ void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath)
type=3; type=3;
// extract new material's name // extract new material's name
c8 textureNameBuf[WORD_BUFFER_LENGTH]; c8 textureNameBuf[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// handle options // handle options
while (textureNameBuf[0]=='-') while (textureNameBuf[0]=='-')
{ {
if (!strncmp(bufPtr,"-blendu",7)) if (!strncmp(bufPtr,"-blendu",7))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!strncmp(bufPtr,"-blendv",7)) if (!strncmp(bufPtr,"-blendv",7))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!strncmp(bufPtr,"-cc",3)) if (!strncmp(bufPtr,"-cc",3))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!strncmp(bufPtr,"-clamp",6)) if (!strncmp(bufPtr,"-clamp",6))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!strncmp(bufPtr,"-texres",7)) if (!strncmp(bufPtr,"-texres",7))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!strncmp(bufPtr,"-mm",3)) if (!strncmp(bufPtr,"-mm",3))
{ {
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
} }
if (!strncmp(bufPtr,"-o",2)) if (!strncmp(bufPtr,"-o",2))
{ {
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// next parameters are optional, so skip rest of loop if no number is found // next parameters are optional, so skip rest of loop if no number is found
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!core::isdigit(textureNameBuf[0])) if (!core::isdigit(textureNameBuf[0]))
continue; continue;
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!core::isdigit(textureNameBuf[0])) if (!core::isdigit(textureNameBuf[0]))
continue; continue;
} }
if (!strncmp(bufPtr,"-s",2)) if (!strncmp(bufPtr,"-s",2))
{ {
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// next parameters are optional, so skip rest of loop if no number is found // next parameters are optional, so skip rest of loop if no number is found
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!core::isdigit(textureNameBuf[0])) if (!core::isdigit(textureNameBuf[0]))
continue; continue;
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!core::isdigit(textureNameBuf[0])) if (!core::isdigit(textureNameBuf[0]))
continue; continue;
} }
if (!strncmp(bufPtr,"-t",2)) if (!strncmp(bufPtr,"-t",2))
{ {
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// next parameters are optional, so skip rest of loop if no number is found // next parameters are optional, so skip rest of loop if no number is found
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!core::isdigit(textureNameBuf[0])) if (!core::isdigit(textureNameBuf[0]))
continue; continue;
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
if (!core::isdigit(textureNameBuf[0])) if (!core::isdigit(textureNameBuf[0]))
continue; continue;
} }
// get next word // get next word
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
} }
if (type==1) if (type==1)
{ {
pCurrMaterial->Meshbuffer->Material.MaterialTypeParam=core::fast_atof(textureNameBuf); currMaterial->Meshbuffer->Material.MaterialTypeParam=core::fast_atof(textureNameBuf);
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
} }
video::ITexture * pTexture; video::ITexture * texture = 0;
if (FileSystem->existFile(textureNameBuf)) if (FileSystem->existFile(textureNameBuf))
pTexture = Driver->getTexture( textureNameBuf ); texture = Driver->getTexture( textureNameBuf );
else else
// try to read in the relative path, the .obj is loaded from // try to read in the relative path, the .obj is loaded from
pTexture = Driver->getTexture( (relPath + textureNameBuf).c_str() ); texture = Driver->getTexture( (relPath + textureNameBuf).c_str() );
if ( pTexture ) if ( texture )
{ {
if (type==0) if (type==0)
pCurrMaterial->Meshbuffer->Material.setTexture(0, pTexture); currMaterial->Meshbuffer->Material.setTexture(0, texture);
else if (type==1) else if (type==1)
{ {
Driver->makeNormalMapTexture(pTexture); Driver->makeNormalMapTexture(texture);
pCurrMaterial->Meshbuffer->Material.setTexture(1, pTexture); currMaterial->Meshbuffer->Material.setTexture(1, texture);
pCurrMaterial->Meshbuffer->Material.MaterialType=video::EMT_PARALLAX_MAP_SOLID; currMaterial->Meshbuffer->Material.MaterialType=video::EMT_PARALLAX_MAP_SOLID;
} }
else if (type==2) else if (type==2)
{ {
pCurrMaterial->Meshbuffer->Material.setTexture(0, pTexture); currMaterial->Meshbuffer->Material.setTexture(0, texture);
pCurrMaterial->Meshbuffer->Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; currMaterial->Meshbuffer->Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR;
} }
else if (type==3) else if (type==3)
{ {
// pCurrMaterial->Meshbuffer->Material.Textures[1] = pTexture; // currMaterial->Meshbuffer->Material.Textures[1] = texture;
// pCurrMaterial->Meshbuffer->Material.MaterialType=video::EMT_REFLECTION_2_LAYER; // currMaterial->Meshbuffer->Material.MaterialType=video::EMT_REFLECTION_2_LAYER;
} }
// Set diffuse material colour to white so as not to affect texture colour // Set diffuse material colour to white so as not to affect texture colour
// Because Maya set diffuse colour Kd to black when you use a diffuse colour map // Because Maya set diffuse colour Kd to black when you use a diffuse colour map
// But is this the right thing to do? // But is this the right thing to do?
pCurrMaterial->Meshbuffer->Material.DiffuseColor.set( currMaterial->Meshbuffer->Material.DiffuseColor.set(
pCurrMaterial->Meshbuffer->Material.DiffuseColor.getAlpha(), 255, 255, 255 ); currMaterial->Meshbuffer->Material.DiffuseColor.getAlpha(), 255, 255, 255 );
} }
} }
break; break;
case 'd': // d - transparency case 'd': // d - transparency
if ( pCurrMaterial ) if ( currMaterial )
{ {
const u32 COLOR_BUFFER_LENGTH = 16; const u32 COLOR_BUFFER_LENGTH = 16;
c8 dStr[COLOR_BUFFER_LENGTH]; c8 dStr[COLOR_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(dStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(dStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
f32 dValue = core::fast_atof(dStr); f32 dValue = core::fast_atof(dStr);
pCurrMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(dValue * 255) ); currMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(dValue * 255) );
if (dValue<1.0f) if (dValue<1.0f)
pCurrMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; currMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
} }
break; break;
case 'T': case 'T':
if ( pCurrMaterial ) if ( currMaterial )
{ {
switch ( bufPtr[1] ) switch ( bufPtr[1] )
{ {
...@@ -498,15 +512,15 @@ void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath) ...@@ -498,15 +512,15 @@ void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath)
c8 greenStr[COLOR_BUFFER_LENGTH]; c8 greenStr[COLOR_BUFFER_LENGTH];
c8 blueStr[COLOR_BUFFER_LENGTH]; c8 blueStr[COLOR_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(redStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(redStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
bufPtr = goAndCopyNextWord(greenStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(greenStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
bufPtr = goAndCopyNextWord(blueStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(blueStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
f32 transparency = ( core::fast_atof(redStr) + core::fast_atof(greenStr) + core::fast_atof(blueStr) ) / 3; f32 transparency = ( core::fast_atof(redStr) + core::fast_atof(greenStr) + core::fast_atof(blueStr) ) / 3;
pCurrMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(transparency * 255) ); currMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(transparency * 255) );
if (transparency < 1.0f) if (transparency < 1.0f)
pCurrMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; currMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
} }
} }
break; break;
...@@ -514,84 +528,84 @@ void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath) ...@@ -514,84 +528,84 @@ void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath)
break; break;
} // end switch(bufPtr[0]) } // end switch(bufPtr[0])
// go to next line // go to next line
bufPtr = goNextLine(bufPtr, pBufEnd); bufPtr = goNextLine(bufPtr, bufEnd);
} // end while (bufPtr) } // end while (bufPtr)
// end of file. if there's an existing material, store it // end of file. if there's an existing material, store it
if ( pCurrMaterial ) if ( currMaterial )
{ {
materials.push_back( pCurrMaterial ); materials.push_back( currMaterial );
pCurrMaterial = 0; currMaterial = 0;
} }
delete [] pBuf; delete [] buf;
pMtlReader->drop(); mtlReader->drop();
} }
//! Read RGB color //! Read RGB color
const c8* COBJMeshFileLoader::readColor(const c8* bufPtr, video::SColor& color, const c8* const pBufEnd) const c8* COBJMeshFileLoader::readColor(const c8* bufPtr, video::SColor& color, const c8* const bufEnd)
{ {
const u32 COLOR_BUFFER_LENGTH = 16; const u32 COLOR_BUFFER_LENGTH = 16;
c8 colStr[COLOR_BUFFER_LENGTH]; c8 colStr[COLOR_BUFFER_LENGTH];
color.setAlpha(255); color.setAlpha(255);
bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
color.setRed((s32)(core::fast_atof(colStr) * 255.0f)); color.setRed((s32)(core::fast_atof(colStr) * 255.0f));
bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
color.setGreen((s32)(core::fast_atof(colStr) * 255.0f)); color.setGreen((s32)(core::fast_atof(colStr) * 255.0f));
bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd);
color.setBlue((s32)(core::fast_atof(colStr) * 255.0f)); color.setBlue((s32)(core::fast_atof(colStr) * 255.0f));
return bufPtr; return bufPtr;
} }
//! Read 3d vector of floats //! Read 3d vector of floats
const c8* COBJMeshFileLoader::readVec3(const c8* bufPtr, core::vector3df& vec, const c8* const pBufEnd) const c8* COBJMeshFileLoader::readVec3(const c8* bufPtr, core::vector3df& vec, const c8* const bufEnd)
{ {
const u32 WORD_BUFFER_LENGTH = 256; const u32 WORD_BUFFER_LENGTH = 256;
c8 wordBuffer[WORD_BUFFER_LENGTH]; c8 wordBuffer[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
vec.X=-core::fast_atof(wordBuffer); // change handedness vec.X=-core::fast_atof(wordBuffer); // change handedness
bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
vec.Y=core::fast_atof(wordBuffer); vec.Y=core::fast_atof(wordBuffer);
bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
vec.Z=core::fast_atof(wordBuffer); vec.Z=core::fast_atof(wordBuffer);
return bufPtr; return bufPtr;
} }
//! Read 2d vector of floats //! Read 2d vector of floats
const c8* COBJMeshFileLoader::readVec2(const c8* bufPtr, core::vector2df& vec, const c8* const pBufEnd) const c8* COBJMeshFileLoader::readVec2(const c8* bufPtr, core::vector2df& vec, const c8* const bufEnd)
{ {
const u32 WORD_BUFFER_LENGTH = 256; const u32 WORD_BUFFER_LENGTH = 256;
c8 wordBuffer[WORD_BUFFER_LENGTH]; c8 wordBuffer[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
vec.X=core::fast_atof(wordBuffer); vec.X=core::fast_atof(wordBuffer);
bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
vec.Y=-core::fast_atof(wordBuffer); // change handedness vec.Y=-core::fast_atof(wordBuffer); // change handedness
return bufPtr; return bufPtr;
} }
//! Read boolean value represented as 'on' or 'off' //! Read boolean value represented as 'on' or 'off'
const c8* COBJMeshFileLoader::readBool(const c8* bufPtr, bool& tf, const c8* const pBufEnd) const c8* COBJMeshFileLoader::readBool(const c8* bufPtr, bool& tf, const c8* const bufEnd)
{ {
const u32 BUFFER_LENGTH = 8; const u32 BUFFER_LENGTH = 8;
c8 tfStr[BUFFER_LENGTH]; c8 tfStr[BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(tfStr, bufPtr, BUFFER_LENGTH, pBufEnd); bufPtr = goAndCopyNextWord(tfStr, bufPtr, BUFFER_LENGTH, bufEnd);
tf = strcmp(tfStr, "off") != 0; tf = strcmp(tfStr, "off") != 0;
return bufPtr; return bufPtr;
} }
COBJMeshFileLoader::SObjMtl* COBJMeshFileLoader::findMtl(const c8* pMtlName) COBJMeshFileLoader::SObjMtl* COBJMeshFileLoader::findMtl(const c8* mtlName)
{ {
for (u32 i = 0; i < materials.size(); ++i) for (u32 i = 0; i < materials.size(); ++i)
{ {
if ( materials[i]->name == pMtlName ) if ( materials[i]->Name == mtlName )
return materials[i]; return materials[i];
} }
return 0; return 0;
...@@ -600,10 +614,10 @@ COBJMeshFileLoader::SObjMtl* COBJMeshFileLoader::findMtl(const c8* pMtlName) ...@@ -600,10 +614,10 @@ COBJMeshFileLoader::SObjMtl* COBJMeshFileLoader::findMtl(const c8* pMtlName)
//! skip space characters and stop on first non-space //! skip space characters and stop on first non-space
const c8* COBJMeshFileLoader::goFirstWord(const c8* buf, const c8* const pBufEnd) const c8* COBJMeshFileLoader::goFirstWord(const c8* buf, const c8* const bufEnd)
{ {
// skip space characters // skip space characters
while((buf != pBufEnd) && core::isspace(*buf)) while((buf != bufEnd) && core::isspace(*buf))
++buf; ++buf;
return buf; return buf;
...@@ -611,32 +625,32 @@ const c8* COBJMeshFileLoader::goFirstWord(const c8* buf, const c8* const pBufEnd ...@@ -611,32 +625,32 @@ const c8* COBJMeshFileLoader::goFirstWord(const c8* buf, const c8* const pBufEnd
//! skip current word and stop at beginning of next one //! skip current word and stop at beginning of next one
const c8* COBJMeshFileLoader::goNextWord(const c8* buf, const c8* const pBufEnd) const c8* COBJMeshFileLoader::goNextWord(const c8* buf, const c8* const bufEnd)
{ {
// skip current word // skip current word
while(( buf != pBufEnd ) && !core::isspace(*buf)) while(( buf != bufEnd ) && !core::isspace(*buf))
++buf; ++buf;
return goFirstWord(buf, pBufEnd); return goFirstWord(buf, bufEnd);
} }
//! Read until line break is reached and stop at the next non-space character //! Read until line break is reached and stop at the next non-space character
const c8* COBJMeshFileLoader::goNextLine(const c8* buf, const c8* const pBufEnd) const c8* COBJMeshFileLoader::goNextLine(const c8* buf, const c8* const bufEnd)
{ {
// look for newline characters // look for newline characters
while(buf != pBufEnd) while(buf != bufEnd)
{ {
// found it, so leave // found it, so leave
if (*buf=='\n' || *buf=='\r') if (*buf=='\n' || *buf=='\r')
break; break;
++buf; ++buf;
} }
return goFirstWord(buf, pBufEnd); return goFirstWord(buf, bufEnd);
} }
u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLength, const c8* const pBufEnd) u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLength, const c8* const bufEnd)
{ {
if (!outBufLength) if (!outBufLength)
return 0; return 0;
...@@ -649,7 +663,7 @@ u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLe ...@@ -649,7 +663,7 @@ u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLe
u32 i = 0; u32 i = 0;
while(inBuf[i]) while(inBuf[i])
{ {
if (core::isspace(inBuf[i]) || &(inBuf[i]) == pBufEnd) if (core::isspace(inBuf[i]) || &(inBuf[i]) == bufEnd)
break; break;
++i; ++i;
} }
...@@ -663,13 +677,13 @@ u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLe ...@@ -663,13 +677,13 @@ u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLe
} }
core::stringc COBJMeshFileLoader::copyLine(const c8* inBuf, const c8* pBufEnd) core::stringc COBJMeshFileLoader::copyLine(const c8* inBuf, const c8* bufEnd)
{ {
if (!inBuf) if (!inBuf)
return core::stringc(); return core::stringc();
const c8* ptr = inBuf; const c8* ptr = inBuf;
while (ptr<pBufEnd) while (ptr<bufEnd)
{ {
if (*ptr=='\n' || *ptr=='\r') if (*ptr=='\n' || *ptr=='\r')
break; break;
...@@ -679,59 +693,59 @@ core::stringc COBJMeshFileLoader::copyLine(const c8* inBuf, const c8* pBufEnd) ...@@ -679,59 +693,59 @@ core::stringc COBJMeshFileLoader::copyLine(const c8* inBuf, const c8* pBufEnd)
} }
const c8* COBJMeshFileLoader::goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* pBufEnd) const c8* COBJMeshFileLoader::goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* bufEnd)
{ {
inBuf = goNextWord(inBuf, pBufEnd); inBuf = goNextWord(inBuf, bufEnd);
copyWord(outBuf, inBuf, outBufLength, pBufEnd); copyWord(outBuf, inBuf, outBufLength, bufEnd);
return inBuf; return inBuf;
} }
bool COBJMeshFileLoader::retrieveVertexIndices(c8* pVertexData, s32* pIdx, const c8* pBufEnd, u32 vbsize, u32 vtsize, u32 vnsize) bool COBJMeshFileLoader::retrieveVertexIndices(c8* vertexData, s32* idx, const c8* bufEnd, u32 vbsize, u32 vtsize, u32 vnsize)
{ {
c8 word[16] = ""; c8 word[16] = "";
const c8* pChar = goFirstWord(pVertexData, pBufEnd); const c8* p = goFirstWord(vertexData, bufEnd);
u32 idxType = 0; // 0 = posIdx, 1 = texcoordIdx, 2 = normalIdx u32 idxType = 0; // 0 = posIdx, 1 = texcoordIdx, 2 = normalIdx
u32 i = 0; u32 i = 0;
while ( pChar != pBufEnd ) while ( p != bufEnd )
{ {
if ( ( core::isdigit(*pChar)) || (*pChar == '-') ) if ( ( core::isdigit(*p)) || (*p == '-') )
{ {
// build up the number // build up the number
word[i++] = *pChar; word[i++] = *p;
} }
else if ( *pChar == '/' || *pChar == ' ' || *pChar == '\0' ) else if ( *p == '/' || *p == ' ' || *p == '\0' )
{ {
// number is completed. Convert and store it // number is completed. Convert and store it
word[i] = '\0'; word[i] = '\0';
// if no number was found index will become 0 and later on -1 by decrement // if no number was found index will become 0 and later on -1 by decrement
if (word[0]=='-') if (word[0]=='-')
{ {
pIdx[idxType] = core::strtol10(word+1,0); idx[idxType] = core::strtol10(word+1,0);
pIdx[idxType] *= -1; idx[idxType] *= -1;
switch (idxType) switch (idxType)
{ {
case 0: case 0:
pIdx[idxType] += vbsize; idx[idxType] += vbsize;
break; break;
case 1: case 1:
pIdx[idxType] += vtsize; idx[idxType] += vtsize;
break; break;
case 2: case 2:
pIdx[idxType] += vnsize; idx[idxType] += vnsize;
break; break;
} }
} }
else else
pIdx[idxType] = core::strtol10(word,0)-1; idx[idxType] = core::strtol10(word,0)-1;
// reset the word // reset the word
word[0] = '\0'; word[0] = '\0';
i = 0; i = 0;
// go to the next kind of index type // go to the next kind of index type
if (*pChar == '/') if (*p == '/')
{ {
if ( ++idxType > 2 ) if ( ++idxType > 2 )
{ {
...@@ -743,14 +757,14 @@ bool COBJMeshFileLoader::retrieveVertexIndices(c8* pVertexData, s32* pIdx, const ...@@ -743,14 +757,14 @@ bool COBJMeshFileLoader::retrieveVertexIndices(c8* pVertexData, s32* pIdx, const
{ {
// set all missing values to disable (=-1) // set all missing values to disable (=-1)
while (++idxType < 3) while (++idxType < 3)
pIdx[idxType]=-1; idx[idxType]=-1;
++pChar; ++p;
break; // while break; // while
} }
} }
// go to the next char // go to the next char
++pChar; ++p;
} }
return true; return true;
......
...@@ -41,7 +41,7 @@ private: ...@@ -41,7 +41,7 @@ private:
struct SObjMtl struct SObjMtl
{ {
SObjMtl() : Meshbuffer(0), illumination(0) { SObjMtl() : Meshbuffer(0), Illumination(0) {
Meshbuffer = new SMeshBuffer(); Meshbuffer = new SMeshBuffer();
Meshbuffer->Material.Shininess = 0.0f; Meshbuffer->Material.Shininess = 0.0f;
Meshbuffer->Material.AmbientColor = video::SColorf(0.2f, 0.2f, 0.2f, 1.0f).toSColor(); Meshbuffer->Material.AmbientColor = video::SColorf(0.2f, 0.2f, 0.2f, 1.0f).toSColor();
...@@ -49,44 +49,44 @@ private: ...@@ -49,44 +49,44 @@ private:
Meshbuffer->Material.SpecularColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f).toSColor(); Meshbuffer->Material.SpecularColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f).toSColor();
} }
SObjMtl(SObjMtl& o) : Meshbuffer(o.Meshbuffer), name(o.name), illumination(o.illumination) { o.Meshbuffer->grab(); } SObjMtl(SObjMtl& o) : Meshbuffer(o.Meshbuffer), Name(o.Name), Illumination(o.Illumination) { o.Meshbuffer->grab(); }
scene::SMeshBuffer *Meshbuffer; scene::SMeshBuffer *Meshbuffer;
core::stringc name; core::stringc Name;
c8 illumination; c8 Illumination;
}; };
// returns a pointer to the first printable character available in the buffer // returns a pointer to the first printable character available in the buffer
const c8* goFirstWord(const c8* buf, const c8* const pBufEnd); const c8* goFirstWord(const c8* buf, const c8* const bufEnd);
// returns a pointer to the first printable character after the first non-printable // returns a pointer to the first printable character after the first non-printable
const c8* goNextWord(const c8* buf, const c8* const pBufEnd); const c8* goNextWord(const c8* buf, const c8* const bufEnd);
// returns a pointer to the next printable character after the first line break // returns a pointer to the next printable character after the first line break
const c8* goNextLine(const c8* buf, const c8* const pBufEnd); const c8* goNextLine(const c8* buf, const c8* const bufEnd);
// copies the current word from the inBuf to the outBuf // copies the current word from the inBuf to the outBuf
u32 copyWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd); u32 copyWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd);
// copies the current line from the inBuf to the outBuf // copies the current line from the inBuf to the outBuf
core::stringc copyLine(const c8* inBuf, const c8* const pBufEnd); core::stringc copyLine(const c8* inBuf, const c8* const bufEnd);
// combination of goNextWord followed by copyWord // combination of goNextWord followed by copyWord
const c8* goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd); const c8* goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd);
//! Read the material from the given file //! Read the material from the given file
void readMTL(const c8* pFileName, core::stringc relPath); void readMTL(const c8* fileName, core::stringc relPath);
//! Find and return the material with the given name //! Find and return the material with the given name
SObjMtl * findMtl(const c8* pMtlName); SObjMtl * findMtl(const c8* mtlName);
//! Read RGB color //! Read RGB color
const c8* readColor(const c8* pBufPtr, video::SColor& color, const c8* const pBufEnd); const c8* readColor(const c8* bufPtr, video::SColor& color, const c8* const pBufEnd);
//! Read 3d vector of floats //! Read 3d vector of floats
const c8* readVec3(const c8* pBufPtr, core::vector3df& vec, const c8* const pBufEnd); const c8* readVec3(const c8* bufPtr, core::vector3df& vec, const c8* const pBufEnd);
//! Read 2d vector of floats //! Read 2d vector of floats
const c8* readVec2(const c8* pBufPtr, core::vector2df& vec, const c8* const pBufEnd); const c8* readVec2(const c8* bufPtr, core::vector2df& vec, const c8* const pBufEnd);
//! Read boolean value represented as 'on' or 'off' //! Read boolean value represented as 'on' or 'off'
const c8* readBool(const c8* pBufPtr, bool& tf, const c8* const pBufEnd); const c8* readBool(const c8* bufPtr, bool& tf, const c8* const bufEnd);
// reads and convert to integer the vertex indices in a line of obj file's face statement // reads and convert to integer the vertex indices in a line of obj file's face statement
// -1 for the index if it doesn't exist // -1 for the index if it doesn't exist
// indices are changed to 0-based index instead of 1-based from the obj file // indices are changed to 0-based index instead of 1-based from the obj file
bool retrieveVertexIndices(c8* pVertexData, s32* Idx, const c8* pBufEnd, u32 vbsize, u32 vtsize, u32 vnsize); bool retrieveVertexIndices(c8* vertexData, s32* idx, const c8* bufEnd, u32 vbsize, u32 vtsize, u32 vnsize);
void cleanUp(); void cleanUp();
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -418,11 +418,8 @@ namespace scene ...@@ -418,11 +418,8 @@ namespace scene
// Do Not call ISceneNode::OnRegisterSceneNode ( ), this node should have no children // Do Not call ISceneNode::OnRegisterSceneNode ( ), this node should have no children
// Determine the camera rotation, based on the camera direction. // Determine the camera rotation, based on the camera direction.
core::line3d<f32> line; const core::vector3df cameraPosition = SceneManager->getActiveCamera()->getAbsolutePosition();
line.start = SceneManager->getActiveCamera()->getAbsolutePosition(); const core::vector3df cameraRotation = core::line3d<f32>(cameraPosition, SceneManager->getActiveCamera()->getTarget()).getVector().getHorizontalAngle();
line.end = SceneManager->getActiveCamera()->getTarget();
core::vector3df cameraRotation = line.getVector().getHorizontalAngle();
core::vector3df cameraPosition = SceneManager->getActiveCamera()->getPosition ( );
// Only check on the Camera's Y Rotation // Only check on the Camera's Y Rotation
if (!ForceRecalculation) if (!ForceRecalculation)
...@@ -449,7 +446,7 @@ namespace scene ...@@ -449,7 +446,7 @@ namespace scene
{ {
if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) ) if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) )
{ {
f32 distance = (cameraPosition.X - TerrainData.Patches[j].Center.X) * (cameraPosition.X - TerrainData.Patches[j].Center.X) + const f32 distance = (cameraPosition.X - TerrainData.Patches[j].Center.X) * (cameraPosition.X - TerrainData.Patches[j].Center.X) +
(cameraPosition.Y - TerrainData.Patches[j].Center.Y) * (cameraPosition.Y - TerrainData.Patches[j].Center.Y) + (cameraPosition.Y - TerrainData.Patches[j].Center.Y) * (cameraPosition.Y - TerrainData.Patches[j].Center.Y) +
(cameraPosition.Z - TerrainData.Patches[j].Center.Z) * (cameraPosition.Z - TerrainData.Patches[j].Center.Z); (cameraPosition.Z - TerrainData.Patches[j].Center.Z) * (cameraPosition.Z - TerrainData.Patches[j].Center.Z);
......
...@@ -161,7 +161,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -161,7 +161,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{ {
for (u32 id=i*3+0;id<=i*3+2;++id) for (u32 id=i*3+0;id<=i*3+2;++id)
{ {
core::array< u32 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ];
bool found=false; bool found=false;
for (u32 j=0; j < Array.size(); ++j) for (u32 j=0; j < Array.size(); ++j)
...@@ -212,29 +212,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -212,29 +212,30 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
} }
} }
for (u32 j=0;j<mesh->Weights.size();++j) for (u32 j=0;j<mesh->WeightJoint.size();++j)
{ {
ISkinnedMesh::SWeight& Weight = (*mesh->Weights[j]); ISkinnedMesh::SWeight& weight = (AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]->Weights[mesh->WeightNum[j]]);
u32 id = Weight.vertex_id; u32 id = weight.vertex_id;
if (id>=verticesLinkIndex.size()) if (id>=verticesLinkIndex.size())
{ {
os::Printer::log("X loader: Weight id out of range", ELL_WARNING); os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0; id=0;
weight.strength=0.f;
} }
if (verticesLinkBuffer[id].size()==1) if (verticesLinkBuffer[id].size()==1)
{ {
Weight.vertex_id=verticesLinkIndex[id][0]; weight.vertex_id=verticesLinkIndex[id][0];
Weight.buffer_id=verticesLinkBuffer[id][0]; weight.buffer_id=verticesLinkBuffer[id][0];
} }
else if (verticesLinkBuffer[id].size() != 0) else if (verticesLinkBuffer[id].size() != 0)
{ {
for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k) for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k)
{ {
ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(Joint); ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(joint);
WeightClone->strength = Weight.strength; WeightClone->strength = weight.strength;
WeightClone->vertex_id = verticesLinkIndex[id][k]; WeightClone->vertex_id = verticesLinkIndex[id][k];
WeightClone->buffer_id = verticesLinkBuffer[id][k]; WeightClone->buffer_id = verticesLinkBuffer[id][k];
} }
...@@ -298,20 +299,21 @@ bool CXMeshFileLoader::load(io::IReadFile* file) ...@@ -298,20 +299,21 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
} }
for (u32 j=0;j<mesh->Weights.size();++j) for (u32 j=0;j<mesh->WeightJoint.size();++j)
{ {
ISkinnedMesh::SWeight* weight = mesh->Weights[j]; ISkinnedMesh::SWeight& weight = (AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]->Weights[mesh->WeightNum[j]]);
u32 id = weight->vertex_id; u32 id = weight.vertex_id;
if (id>=verticesLinkIndex.size()) if (id>=verticesLinkIndex.size())
{ {
os::Printer::log("X loader: Weight id out of range", ELL_WARNING); os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0; id=0;
weight.strength=0.f;
} }
weight->vertex_id=verticesLinkIndex[id]; weight.vertex_id=verticesLinkIndex[id];
weight->buffer_id=verticesLinkBuffer[id] + bufferOffset;; weight.buffer_id=verticesLinkBuffer[id] + bufferOffset;;
} }
} }
#endif #endif
...@@ -846,7 +848,8 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) ...@@ -846,7 +848,8 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
CSkinnedMesh::SJoint *joint=0; CSkinnedMesh::SJoint *joint=0;
for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n) u32 n;
for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
{ {
if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName) if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName)
{ {
...@@ -860,6 +863,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) ...@@ -860,6 +863,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
os::Printer::log("creating joint for skinning ", TransformNodeName.c_str()); os::Printer::log("creating joint for skinning ", TransformNodeName.c_str());
#endif #endif
n = AnimatedMesh->getAllJoints().size();
joint=AnimatedMesh->createJoint(0); joint=AnimatedMesh->createJoint(0);
joint->Name=TransformNodeName; joint->Name=TransformNodeName;
} }
...@@ -873,16 +877,18 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) ...@@ -873,16 +877,18 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
const u32 jointStart = joint->Weights.size(); const u32 jointStart = joint->Weights.size();
joint->Weights.reallocate(jointStart+nWeights); joint->Weights.reallocate(jointStart+nWeights);
mesh.Weights.reallocate( mesh.Weights.size() + nWeights ); mesh.WeightJoint.reallocate( mesh.WeightJoint.size() + nWeights );
mesh.WeightNum.reallocate( mesh.WeightNum.size() + nWeights );
for (i=0; i<nWeights; ++i) for (i=0; i<nWeights; ++i)
{ {
mesh.WeightJoint.push_back(n);
mesh.WeightNum.push_back(joint->Weights.size());
CSkinnedMesh::SWeight *weight=AnimatedMesh->createWeight(joint); CSkinnedMesh::SWeight *weight=AnimatedMesh->createWeight(joint);
weight->buffer_id=0; weight->buffer_id=0;
weight->vertex_id=readInt(); weight->vertex_id=readInt();
mesh.Weights.push_back(weight);
} }
// read vertex weights // read vertex weights
......
...@@ -78,7 +78,8 @@ public: ...@@ -78,7 +78,8 @@ public:
bool HasSkinning; bool HasSkinning;
bool HasVertexColors; bool HasVertexColors;
core::array<ISkinnedMesh::SWeight*> Weights; core::array<u32> WeightJoint;
core::array<u32> WeightNum;
}; };
private: private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment