Commit 99aa627e authored by hybrid's avatar hybrid

Merged from 1.4 branch revisions 1174:1188

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1189 dfc29bdd-3216-0410-991c-e03cc46cb475
parent f73f392e
......@@ -14,54 +14,41 @@ using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
/*
In this tutorial, one of our goals is to move a scene node using some
keys on the keyboard. We store a pointer to the scene node we want to
move with the keys here.
The other pointer is a pointer to the Irrlicht Device, which we need
int the EventReceiver to manipulate the scene node and to get the
active camera.
*/
scene::ISceneNode* node = 0;
IrrlichtDevice* device = 0;
/*
To get events like mouse and keyboard input, or GUI events like
"the OK button has been clicked", we need an object wich is derived from the
To receive events like mouse and keyboard input, or GUI events like
"the OK button has been clicked", we need an object which is derived from the
IEventReceiver object. There is only one method to override: OnEvent.
This method will be called by the engine when an event happened.
We will use this input to move the scene node with the keys W and S.
This method will be called by the engine once when an event happens.
What we really want to know is whether a key is being held down,
and so we will remember the current state of each key.
*/
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
/*
If the key 'W' or 'S' was left up, we get the position of the scene node,
and modify the Y coordinate a little bit. So if you press 'W', the node
moves up, and if you press 'S' it moves down.
*/
if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
!event.KeyInput.PressedDown)
{
switch(event.KeyInput.Key)
{
case KEY_KEY_W:
case KEY_KEY_S:
{
core::vector3df v = node->getPosition();
v.Y += event.KeyInput.Key == KEY_KEY_W ? 2.0f : -2.0f;
node->setPosition(v);
}
return true;
}
}
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
......@@ -117,20 +104,23 @@ int main()
interesting. Because we have no dynamic lights in this scene we disable
lighting for each model (otherwise the models would be black).
*/
node = smgr->addSphereSceneNode();
node->setPosition(core::vector3df(0,0,30));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ISceneNode * node = smgr->addSphereSceneNode();
if (node)
{
node->setPosition(core::vector3df(0,0,30));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
}
/*
Now we create another node, moving using a scene node animator. Scene node
animators modify scene nodes and can be attached to any scene node like
mesh scene nodes, billboards, lights and even camera scene nodes. Scene node
animators are not only able to modify the position of a scene node, they can
also animate the textures of an object for example.
We create a cube scene node and attach a 'fly circle' scene node to it, letting
this node fly around our sphere scene node.
Now we create another node, moving using a scene node animator. Scene
node animators modify scene nodes and can be attached to any scene node
like mesh scene nodes, billboards, lights and even camera scene nodes.
Scene node animators are not only able to modify the position of a
scene node, they can also animate the textures of an object for
example. We create a cube scene node and attach a 'fly circle' scene
node to it, letting this node fly around our sphere scene node.
*/
scene::ISceneNode* n = smgr->addCubeSceneNode();
......@@ -140,8 +130,11 @@ int main()
n->setMaterialFlag(video::EMF_LIGHTING, false);
scene::ISceneNodeAnimator* anim =
smgr->createFlyCircleAnimator(core::vector3df(0,0,30), 20.0f);
n->addAnimator(anim);
anim->drop();
if (anim)
{
n->addAnimator(anim);
anim->drop();
}
}
/*
......@@ -155,8 +148,11 @@ int main()
scene::ISceneNodeAnimator* anim =
smgr->createFlyStraightAnimator(core::vector3df(100,0,60),
core::vector3df(-100,0,60), 2500, true);
anms->addAnimator(anim);
anim->drop();
if (anim)
{
anms->addAnimator(anim);
anim->drop();
}
/*
To make to model look right we set the frames between which the animation
......@@ -181,9 +177,8 @@ int main()
/*
To be able to look at and move around in this scene,
we create a first person shooter style camera and make the
mouse cursor invisible.
To be able to look at and move around in this scene, we create a first
person shooter style camera and make the mouse cursor invisible.
*/
scene::ICameraSceneNode * cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
device->getCursorControl()->setVisible(false);
......@@ -204,6 +199,22 @@ int main()
while(device->run())
{
/* Check if key W or key S is being held down, and move the
sphere node up or down respectively.
*/
if(receiver.IsKeyDown(irr::KEY_KEY_W))
{
core::vector3df v = node->getPosition();
v.Y += 0.02f;
node->setPosition(v);
}
else if(receiver.IsKeyDown(irr::KEY_KEY_S))
{
core::vector3df v = node->getPosition();
v.Y -= 0.02f;
node->setPosition(v);
}
driver->beginScene(true, true, video::SColor(255,113,113,133));
smgr->drawAll(); // draw the 3d scene
......
......@@ -49,10 +49,14 @@ void CDemo::run()
if ( 0 == device )
return;
device->getFileSystem()->addZipFileArchive("irrlicht.dat");
device->getFileSystem()->addZipFileArchive("../../media/irrlicht.dat");
device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");
if (device->getFileSystem()->existFile("irrlicht.dat"))
device->getFileSystem()->addZipFileArchive("irrlicht.dat");
else
device->getFileSystem()->addZipFileArchive("../../media/irrlicht.dat");
if (device->getFileSystem()->existFile("map-20kdm2.pk3"))
device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
else
device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
......
......@@ -81,8 +81,10 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
device = createDevice( outDriver, //Varmint: 2007/12/18 video::EDT_BURNINGSVIDEO,
core::dimension2d<s32>(512, 384), 16, false, false, false, this);
device->getFileSystem()->addZipFileArchive("irrlicht.dat");
device->getFileSystem()->addZipFileArchive("../../media/irrlicht.dat");
if (device->getFileSystem()->existFile("irrlicht.dat"))
device->getFileSystem()->addZipFileArchive("irrlicht.dat");
else
device->getFileSystem()->addZipFileArchive("../../media/irrlicht.dat");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
......
......@@ -133,6 +133,9 @@ namespace scene
//! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
{
if (vertices == getVertices())
return;
const u32 vertexCount = getVertexCount();
u32 i;
......@@ -153,6 +156,9 @@ namespace scene
//! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other)
{
if (this==other)
return;
const u32 vertexCount = getVertexCount();
u32 i;
......
......@@ -123,9 +123,11 @@ namespace scene
virtual core::vector3df& getNormal(u32 i) = 0;
//! append the vertices and indices to the current buffer
//! Only works for compatible vertex types
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0;
//! append the meshbuffer to the current buffer
//! Only works for compatible vertex types
virtual void append(const IMeshBuffer* const other) = 0;
//! get the current hardware mapping hint
......
This diff is collapsed.
......@@ -222,7 +222,7 @@ namespace scene
//! has got a parent, it is removed from there as child.
virtual void addChild(ISceneNode* child)
{
if (child)
if (child && (child != this))
{
child->grab();
child->remove(); // remove from old parent
......
......@@ -125,20 +125,7 @@ public:
//! \param element: Element to add at the back of the array.
void push_front(const T& element)
{
if (used + 1 > allocated)
reallocate(used +1);
for (u32 i=used; i>0; --i)
{
//data[i] = data[i-1];
allocator.construct(&data[i], data[i-1]);
}
// data[0] = element;
allocator.construct(&data[0], element);
is_sorted = false;
++used;
insert(element);
}
......@@ -154,11 +141,18 @@ public:
if (used + 1 > allocated)
reallocate(used +1);
for (u32 i=used++; i>index; --i)
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], element); // data[index] = element;
is_sorted = false;
++used;
}
......
......@@ -95,6 +95,7 @@ class quaternion
//! axis must be unit length
//! The quaternion representing the rotation is
//! q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)
//! angle in radians
void fromAngleAxis (f32 angle, const vector3df& axis);
//! Fills an angle (radians) around an axis (unit vector)
......@@ -470,6 +471,7 @@ inline void quaternion::fromAngleAxis(f32 angle, const vector3df& axis)
Z = fSin*axis.Z;
}
inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const
{
f32 scale = sqrtf(X*X + Y*Y + Z*Z);
......
......@@ -47,7 +47,7 @@ namespace scene
const core::stringc verticesSectionName = "vertices";
const core::stringc inputTagName = "input";
const core::stringc polygonsSectionName = "polygons";
const core::stringc polygonName = "p";
const core::stringc primitivesName = "p";
const core::stringc nodeSectionName = "node";
const core::stringc lookatNodeName = "lookat";
const core::stringc matrixNodeName = "matrix";
......@@ -60,6 +60,7 @@ namespace scene
const core::stringc minNodeName = "min";
const core::stringc maxNodeName = "max";
const core::stringc instanceNodeName = "instance";
const core::stringc extraNodeName = "extra";
const core::stringc paramTagName = "param";
......@@ -326,16 +327,19 @@ void CColladaFileLoader::readColladaSection(io::IXMLReaderUTF8* reader)
while(reader->read())
if (reader->getNodeType() == io::EXN_ELEMENT)
{
if (librarySectionName == reader->getNodeName())
readLibrarySection(reader);
else
if (assetSectionName == reader->getNodeName())
readAssetSection(reader);
else
if (librarySectionName == reader->getNodeName())
readLibrarySection(reader);
else
if (sceneSectionName == reader->getNodeName())
readSceneSection(reader);
else
{
os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING);
skipSection(reader, true); // unknown section
}
}
}
......@@ -351,25 +355,29 @@ void CColladaFileLoader::readLibrarySection(io::IXMLReaderUTF8* reader)
while(reader->read())
if (reader->getNodeType() == io::EXN_ELEMENT)
{
if (lightPrefabName == reader->getNodeName())
readLightPrefab(reader);
// animation section tbd
if (cameraPrefabName == reader->getNodeName())
readCameraPrefab(reader);
else
// code section tbd
// controller section tbd
if (geometrySectionName == reader->getNodeName())
readGeometry(reader);
else
if (imageSectionName == reader->getNodeName())
readImage(reader);
else
if (textureSectionName == reader->getNodeName())
readTexture(reader);
if (lightPrefabName == reader->getNodeName())
readLightPrefab(reader);
else
if (materialSectionName == reader->getNodeName())
readMaterial(reader);
else
if (cameraPrefabName == reader->getNodeName())
readCameraPrefab(reader);
else
if (geometrySectionName == reader->getNodeName())
readGeometry(reader);
// program section tbd
if (textureSectionName == reader->getNodeName())
readTexture(reader);
else
skipSection(reader, true); // unknown section
skipSection(reader, true); // unknown section, not all allowed supported yet
}
else
if (reader->getNodeType() == io::EXN_ELEMENT_END)
......@@ -414,12 +422,12 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
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 (translateNodeName == reader->getNodeName())
transform *= readTranslateNode(reader);
else
if (bboxNodeName == reader->getNodeName())
readBboxNode(reader, bbox);
else
......@@ -432,7 +440,13 @@ void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader)
readNodeSection(reader, node);
}
else
if (extraNodeName == reader->getNodeName())
skipSection(reader, false);
else
{
os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING);
skipSection(reader, true); // ignore all other sections
}
}
if (node)
node->getRelativeTransformationMatrix() = transform;
......@@ -722,9 +736,14 @@ core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader)
f32 floats[4];
readFloatsInsideElement(reader, floats, 4);
core::quaternion q;
q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2]));
return q.getMatrix();
if (!core::iszero(floats[3]))
{
core::quaternion q;
q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2]));
return q.getMatrix();
}
else
return core::IdentityMatrix;
}
......@@ -802,10 +821,12 @@ void CColladaFileLoader::readCameraPrefab(io::IXMLReaderUTF8* reader)
if (!reader->isEmptyElement())
{
// read techniques optics and imager (the latter is completely ignored, though)
readColladaParameters(reader, cameraPrefabName);
SColladaParam* p;
// XFOV not yet supported
p = getColladaParameter(ECPN_YFOV);
if (p && p->Type == ECPT_FLOAT)
prefab->YFov = p->Floats[0];
......@@ -817,6 +838,7 @@ void CColladaFileLoader::readCameraPrefab(io::IXMLReaderUTF8* reader)
p = getColladaParameter(ECPN_ZFAR);
if (p && p->Type == ECPT_FLOAT)
prefab->ZFar = p->Floats[0];
// orthographic camera uses LEFT, RIGHT, TOP, and BOTTOM
}
Prefabs.push_back(prefab);
......@@ -940,8 +962,8 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
scene::SMesh* mesh = new SMesh();
amesh->addMesh(mesh);
// handles geometry node and the mesh childs in this loop
// read sources with arrays and accessor for each mesh
if (!reader->isEmptyElement())
while(reader->read())
{
......@@ -964,7 +986,7 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
#endif
}
else
if (arraySectionName == nodeName)
if (arraySectionName == nodeName) // child of source
{
// create a new array and read it.
if (!sources.empty())
......@@ -990,7 +1012,7 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
}
else
if (accessorSectionName == nodeName)
if (accessorSectionName == nodeName) // child of source (below a technique tag)
{
SAccessor accessor;
accessor.Count = reader->getAttributeValueAsInt("count");
......@@ -1018,11 +1040,21 @@ void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader)
VertexPositionSource = input->Source;
}
else
// lines and linestrips missing
if (polygonsSectionName == nodeName)
{
// read polygons section
readPolygonSection(reader, VertexPositionSource, sources, mesh);
}
else
// triangles, trifans, and tristrips missing
if (extraNodeName == reader->getNodeName())
skipSection(reader, false);
else
{
// os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING);
skipSection(reader, true); // ignore all other sections
}
} // end if node type is element
else
......@@ -1124,13 +1156,15 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
video::SMaterial mat;
for (u32 matnum=0; matnum<Materials.size(); ++matnum)
{
if (materialName == Materials[matnum].Id)
{
mat = Materials[matnum].Mat;
break;
}
}
// int polygonCount = reader->getAttributeValueAsInt("count");
// int polygonCount = reader->getAttributeValueAsInt("count"); // Not useful because it only determines the number of p tags, not the number of tris
core::array<SInputSlot> slots;
core::array<SPolygon> polygons;
bool parsePolygonOK = false;
......@@ -1144,6 +1178,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
if (reader->getNodeType() == io::EXN_ELEMENT)
{
// polygon node may contain params
if (inputTagName == nodeName)
{
// read input tag
......@@ -1167,7 +1202,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
uriToId(sourceArrayURI);
// find source array (we'll ignore acessors for this implementation)
// find source array (we'll ignore accessors for this implementation)
u32 s;
for (s=0; s<sources.size(); ++s)
if (sources[s].Id == sourceArrayURI)
......@@ -1196,7 +1231,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
}
} // end is input node
else
if (polygonName == nodeName)
if (primitivesName == nodeName)
{
parsePolygonOK = true;
polygons.push_back(SPolygon());
......@@ -1206,7 +1241,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
else
if (reader->getNodeType() == io::EXN_ELEMENT_END)
{
if (polygonName == nodeName)
if (primitivesName == nodeName)
parsePolygonOK = false; // end parsing a polygon
else
if (polygonsSectionName == nodeName)
......
......@@ -665,7 +665,7 @@ bool CIrrDeviceLinux::run()
os::Timer::tick();
#ifdef _IRR_COMPILE_WITH_X11_
if (DriverType != video::EDT_NULL)
if ((DriverType != video::EDT_NULL) && display)
{
SEvent irrevent;
......
......@@ -60,10 +60,6 @@ private:
# error compiler not supported
#endif
struct SLMTSMagigID {
u32 ID;
} PACK_STRUCT;
struct SLMTSHeader
{
u32 MagicID;
......
......@@ -72,7 +72,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
core::array<core::vector3df> normalsBuffer;
SObjMtl * currMtl = new SObjMtl();
currMtl->Name="";
materials.push_back(currMtl);
Materials.push_back(currMtl);
u32 smoothingGroup=0;
core::map<video::S3DVertex, int> vertMap;
......@@ -253,12 +253,12 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
} // end while(bufPtr && (bufPtr-buf<filesize))
// Combine all the groups (meshbuffers) into the mesh
for ( u32 m = 0; m < materials.size(); ++m )
for ( u32 m = 0; m < Materials.size(); ++m )
{
if ( materials[m]->Meshbuffer->getIndexCount() > 0 )
if ( Materials[m]->Meshbuffer->getIndexCount() > 0 )
{
materials[m]->Meshbuffer->recalculateBoundingBox();
mesh->addMeshBuffer( materials[m]->Meshbuffer );
Materials[m]->Meshbuffer->recalculateBoundingBox();
mesh->addMeshBuffer( Materials[m]->Meshbuffer );
}
}
......@@ -315,7 +315,7 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
{
// if there's an existing material, store it first
if ( currMaterial )
materials.push_back( currMaterial );
Materials.push_back( currMaterial );
// extract new material's name
c8 mtlNameBuf[WORD_BUFFER_LENGTH];
......@@ -534,7 +534,7 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
// end of file. if there's an existing material, store it
if ( currMaterial )
{
materials.push_back( currMaterial );
Materials.push_back( currMaterial );
currMaterial = 0;
}
......@@ -603,10 +603,10 @@ const c8* COBJMeshFileLoader::readBool(const c8* bufPtr, bool& tf, const c8* con
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 == mtlName )
return materials[i];
if ( Materials[i]->Name == mtlName )
return Materials[i];
}
return 0;
}
......@@ -775,13 +775,13 @@ void COBJMeshFileLoader::cleanUp()
{
u32 i;
for (i = 0; i < materials.size(); ++i )
for (i = 0; i < Materials.size(); ++i )
{
materials[i]->Meshbuffer->drop();
delete materials[i];
Materials[i]->Meshbuffer->drop();
delete Materials[i];
}
materials.clear();
Materials.clear();
}
......
......@@ -93,7 +93,7 @@ private:
io::IFileSystem* FileSystem;
video::IVideoDriver* Driver;
core::array<SObjMtl*> materials;
core::array<SObjMtl*> Materials;
};
} // end namespace scene
......
......@@ -803,11 +803,11 @@ IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode(
}
//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly
//! and looks like a plane with some hills on it. It is uses mostly for quick
//! tests of the engine only. You can specify how many hills there should be
//! on the plane and how high they should be. Also you must specify a name for
//! the mesh, because the mesh is added to the mesh pool, and can be retrieved
//! again using ISceneManager::getMesh with the name as parameter.
//! and looks like a plane with some hills on it. You can specify how many hills
//! there should be on the plane and how high they should be. Also you must
//! specify a name for the mesh, because the mesh is added to the mesh pool,
//! and can be retrieved again using ISceneManager::getMesh with the name as
//! parameter.
IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name,
const core::dimension2d<f32>& tileSize,
const core::dimension2d<u32>& tileCount,
......@@ -815,9 +815,12 @@ IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name,
const core::dimension2d<f32>& countHills,
const core::dimension2d<f32>& textureRepeatCount)
{
if (!name || MeshCache->isMeshLoaded(name))
if (!name)
return 0;
if (MeshCache->isMeshLoaded(name))
return MeshCache->getMeshByFilename(name);
IMesh* mesh = CGeometryCreator::createHillPlaneMesh(tileSize,
tileCount, material, hillHeight, countHills,
textureRepeatCount);
......@@ -826,11 +829,14 @@ IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name,
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
{
mesh->drop();
return 0;
}
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
animatedMesh->recalculateBoundingBox();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop();
......@@ -846,9 +852,12 @@ IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name,
f32 maxHeight,
const core::dimension2d<s32>& defaultVertexBlockSize)
{
if (!name || MeshCache->isMeshLoaded(name))
if (!name)
return 0;
if (MeshCache->isMeshLoaded(name))
return MeshCache->getMeshByFilename(name);
IMesh* mesh = CGeometryCreator::createTerrainMesh(texture, heightmap,
stretchSize, maxHeight, getVideoDriver(),
defaultVertexBlockSize);
......@@ -857,11 +866,14 @@ IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name,
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
{
mesh->drop();
return 0;
}
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
animatedMesh->recalculateBoundingBox();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop();
......@@ -875,9 +887,12 @@ IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name,
u32 tesselationCylinder, u32 tesselationCone, f32 height,
f32 cylinderHeight, f32 width0,f32 width1)
{
if (!name || MeshCache->isMeshLoaded(name))
if (!name)
return 0;
if (MeshCache->isMeshLoaded(name))
return MeshCache->getMeshByFilename(name);
IMesh* mesh = CGeometryCreator::createArrowMesh( tesselationCylinder,
tesselationCone, height, cylinderHeight, width0,width1,
vtxColor0, vtxColor1);
......@@ -886,11 +901,14 @@ IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name,
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
{
mesh->drop();
return 0;
}
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
animatedMesh->recalculateBoundingBox();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop();
......@@ -904,20 +922,26 @@ IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name,
IAnimatedMesh* CSceneManager::addSphereMesh(const c8* name,
f32 radius, u32 polyCountX, u32 polyCountY)
{
if (!name || MeshCache->isMeshLoaded(name))
if (!name)
return 0;
IMesh* mesh = CGeometryCreator::createSphereMesh( radius, polyCountX, polyCountY);
if (MeshCache->isMeshLoaded(name))
return MeshCache->getMeshByFilename(name);
IMesh* mesh = CGeometryCreator::createSphereMesh(radius, polyCountX, polyCountY);
if (!mesh)
return 0;
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
{
mesh->drop();
return 0;
}
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
animatedMesh->recalculateBoundingBox();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop();
......
......@@ -399,7 +399,7 @@ namespace scene
virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type);
//! Adds a scene node to the scene by name
virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent);
virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent=0);
//! Returns the default scene node animator factory which can create all built-in scene node animators
virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory();
......
......@@ -55,16 +55,15 @@ void CSceneNodeAnimatorTexture::animateNode(ISceneNode* node, u32 timeMs)
{
if (Textures.size())
{
u32 t = (timeMs-StartTime);
s32 idx = 0;
const u32 t = (timeMs-StartTime);
u32 idx = 0;
if (!Loop && timeMs >= EndTime)
idx = Textures.size() - 1;
else
idx = (t/TimePerFrame) % Textures.size();
if (idx < (s32)Textures.size())
if (idx < Textures.size())
node->setMaterialTexture(0, Textures[idx]);
}
}
......
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