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
virtual bool isInputReceiverEnabled() const = 0;
//! 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
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return IsOrthogonal;
}
//! Sets if this camera should return if it 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. */
//! Sets if this camera should return that it is orthogonal.
/** This setting does not change anything of the view or
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 )
{
IsOrthogonal = orthogonal;
......
......@@ -77,6 +77,11 @@ struct S3DVertex
(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
{
return EVT_STANDARD;
......@@ -140,6 +145,11 @@ struct S3DVertex2TCoords : public S3DVertex
(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
{
return EVT_2TCOORDS;
......@@ -192,6 +202,11 @@ struct S3DVertexTangents : public S3DVertex
(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
{
return EVT_TANGENTS;
......
......@@ -285,6 +285,10 @@ namespace video
//! \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; }
//! 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
inline SColor operator+(const SColor& other) const
{
......
......@@ -19,8 +19,8 @@ namespace core
#define DEBUG_CLIENTBLOCK new
#endif
//! Very simple allocator implementation, containers using it are able to
//! be used it across dll boundaries
//! Very simple allocator implementation, containers using it can
//! be used across dll boundaries
template<typename T>
class irrAllocator
{
......
......@@ -102,7 +102,7 @@ namespace core
template<class 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
......
......@@ -104,6 +104,7 @@ namespace core
const f32 ac_bb = (a*c)-(b*b);
f32 z = x+y-ac_bb;
// return sign(z) && !(sign(x)||sign(y))
return (( (IR(z)) & ~((IR(x))|(IR(y))) ) & 0x80000000)!=0;
}
......
......@@ -56,6 +56,9 @@ namespace scene
const core::stringc scaleNodeName = "scale";
const core::stringc translateNodeName = "translate";
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 paramTagName = "param";
......@@ -389,14 +392,50 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
// read the scene
core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
scene::IDummyTransformationSceneNode* node = 0;
while(reader->read())
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())
readNodeSection(reader, SceneManager->getRootSceneNode());
{
// create dummy node if there is none yet.
if (!node)
node = SceneManager->addDummyTransformationSceneNode(SceneManager->getRootSceneNode());
readNodeSection(reader, node);
}
else
skipSection(reader, true); // ignore all other sections
}
if (node)
node->getRelativeTransformationMatrix() = transform;
}
......@@ -426,11 +465,13 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
core::stringc name = reader->getAttributeValue("name"); // name of the node
core::matrix4 transform; // transformation of this node
core::aabbox3df bbox;
scene::ISceneNode* node = 0; // instance
// read the node
while(reader->read())
{
if (reader->getNodeType() == io::EXN_ELEMENT)
{
if (lookatNodeName == reader->getNodeName())
......@@ -454,6 +495,9 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
if (skewNodeName == reader->getNodeName())
transform *= readSkewNode(reader);
else
if (bboxNodeName == reader->getNodeName())
readBboxNode(reader, bbox);
else
if (instanceNodeName == reader->getNodeName())
{
scene::ISceneNode* newnode = 0;
......@@ -497,17 +541,14 @@ void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISce
if (nodeSectionName == reader->getNodeName())
break;
}
}
if (node)
{
// TODO: set transformation correctly into node.
// currently this isn't done correctly. Need to get transformation,
// rotation and scale from the matrix.
const core::vector3df& trans = transform.getTranslation();
const core::vector3df& rot = transform.getRotationDegrees();
node->setPosition(trans);
node->setRotation(rot);
// set transformation correctly into node.
node->setPosition(transform.getTranslation());
node->setRotation(transform.getRotationDegrees());
node->setScale(transform.getScale());
node->updateAbsolutePosition();
node->setName(name.c_str());
......@@ -537,6 +578,7 @@ core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader)
return mat;
}
//! reads a <skew> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader)
{
......@@ -548,16 +590,85 @@ core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader)
if (reader->isEmptyElement())
return mat;
f32 floats[7];
f32 floats[7]; // angle rotation-axis translation-axis
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;
}
//! 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
core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
{
......@@ -574,6 +685,7 @@ core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader)
return mat;
}
//! reads a <perspective> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader)
{
......@@ -595,6 +707,7 @@ core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader
return mat;
}
//! reads a <rotate> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
{
......@@ -609,10 +722,12 @@ core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
f32 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();
}
//! reads a <scale> element and its content and creates a matrix from it
core::matrix4 CColladaFileLoader::readScaleNode(io::IXMLReaderUTF8* reader)
{
......@@ -652,6 +767,7 @@ core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader)
return mat;
}
//! reads a <instance> node and creates a scene node from it
void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent,
scene::ISceneNode** outNode)
......
......@@ -199,6 +199,9 @@ private:
//! reads a <skew> element and its content and creates a matrix from it
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
core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader);
......
This diff is collapsed.
......@@ -41,7 +41,7 @@ private:
struct SObjMtl
{
SObjMtl() : Meshbuffer(0), illumination(0) {
SObjMtl() : Meshbuffer(0), Illumination(0) {
Meshbuffer = new SMeshBuffer();
Meshbuffer->Material.Shininess = 0.0f;
Meshbuffer->Material.AmbientColor = video::SColorf(0.2f, 0.2f, 0.2f, 1.0f).toSColor();
......@@ -49,44 +49,44 @@ private:
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;
core::stringc name;
c8 illumination;
core::stringc Name;
c8 Illumination;
};
// 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
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
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
u32 copyWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd);
// 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
const c8* goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd);
//! 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
SObjMtl * findMtl(const c8* pMtlName);
SObjMtl * findMtl(const c8* mtlName);
//! 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
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
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'
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
// -1 for the index if it doesn't exist
// 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();
......
......@@ -938,7 +938,6 @@ ISceneNode* CSceneManager::getRootSceneNode()
}
//! Returns the current active camera.
//! \return The active camera is returned. Note that this can be NULL, if there
//! was no camera created yet.
......@@ -948,7 +947,6 @@ ICameraSceneNode* CSceneManager::getActiveCamera()
}
//! Sets the active camera. The previous active camera will be deactivated.
//! \param camera: The new camera which should be active.
void CSceneManager::setActiveCamera(ICameraSceneNode* camera)
......@@ -963,8 +961,6 @@ void CSceneManager::setActiveCamera(ICameraSceneNode* camera)
}
//! renders the node.
void CSceneManager::render()
{
......@@ -981,7 +977,6 @@ const core::aabbox3d<f32>& CSceneManager::getBoundingBox() const
}
//! returns if node is culled
bool CSceneManager::isCulled(const ISceneNode* node)
{
......
......@@ -418,11 +418,8 @@ namespace scene
// Do Not call ISceneNode::OnRegisterSceneNode ( ), this node should have no children
// Determine the camera rotation, based on the camera direction.
core::line3d<f32> line;
line.start = SceneManager->getActiveCamera()->getAbsolutePosition();
line.end = SceneManager->getActiveCamera()->getTarget();
core::vector3df cameraRotation = line.getVector().getHorizontalAngle();
core::vector3df cameraPosition = SceneManager->getActiveCamera()->getPosition ( );
const core::vector3df cameraPosition = SceneManager->getActiveCamera()->getAbsolutePosition();
const core::vector3df cameraRotation = core::line3d<f32>(cameraPosition, SceneManager->getActiveCamera()->getTarget()).getVector().getHorizontalAngle();
// Only check on the Camera's Y Rotation
if (!ForceRecalculation)
......@@ -449,7 +446,7 @@ namespace scene
{
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.Z - TerrainData.Patches[j].Center.Z) * (cameraPosition.Z - TerrainData.Patches[j].Center.Z);
......
......@@ -161,7 +161,7 @@ bool CXMeshFileLoader::load(io::IReadFile* file)
{
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;
for (u32 j=0; j < Array.size(); ++j)
......@@ -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())
{
os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0;
weight.strength=0.f;
}
if (verticesLinkBuffer[id].size()==1)
{
Weight.vertex_id=verticesLinkIndex[id][0];
Weight.buffer_id=verticesLinkBuffer[id][0];
weight.vertex_id=verticesLinkIndex[id][0];
weight.buffer_id=verticesLinkBuffer[id][0];
}
else if (verticesLinkBuffer[id].size() != 0)
{
for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k)
{
ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(Joint);
WeightClone->strength = Weight.strength;
ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(joint);
WeightClone->strength = weight.strength;
WeightClone->vertex_id = verticesLinkIndex[id][k];
WeightClone->buffer_id = verticesLinkBuffer[id][k];
}
......@@ -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())
{
os::Printer::log("X loader: Weight id out of range", ELL_WARNING);
id=0;
weight.strength=0.f;
}
weight->vertex_id=verticesLinkIndex[id];
weight->buffer_id=verticesLinkBuffer[id] + bufferOffset;;
weight.vertex_id=verticesLinkIndex[id];
weight.buffer_id=verticesLinkBuffer[id] + bufferOffset;;
}
}
#endif
......@@ -846,7 +848,8 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
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)
{
......@@ -860,6 +863,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
#ifdef _XREADER_DEBUG
os::Printer::log("creating joint for skinning ", TransformNodeName.c_str());
#endif
n = AnimatedMesh->getAllJoints().size();
joint=AnimatedMesh->createJoint(0);
joint->Name=TransformNodeName;
}
......@@ -873,16 +877,18 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
const u32 jointStart = joint->Weights.size();
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)
{
mesh.WeightJoint.push_back(n);
mesh.WeightNum.push_back(joint->Weights.size());
CSkinnedMesh::SWeight *weight=AnimatedMesh->createWeight(joint);
weight->buffer_id=0;
weight->vertex_id=readInt();
mesh.Weights.push_back(weight);
}
// read vertex weights
......
......@@ -78,7 +78,8 @@ public:
bool HasSkinning;
bool HasVertexColors;
core::array<ISkinnedMesh::SWeight*> Weights;
core::array<u32> WeightJoint;
core::array<u32> WeightNum;
};
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