#include "ISceneManager.h"\r
#include "S3DVertex.h"\r
#include "os.h"\r
-#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_\r
-#include "CShadowVolumeSceneNode.h"\r
-#else\r
-#include "IShadowVolumeSceneNode.h"\r
-#endif // _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_\r
-#include "IAnimatedMeshMD3.h"\r
#include "CSkinnedMesh.h"\r
#include "IDummyTransformationSceneNode.h"\r
#include "IBoneSceneNode.h"\r
#include "IMesh.h"\r
#include "IMeshCache.h"\r
#include "IAnimatedMesh.h"\r
+#include "IFileSystem.h"\r
#include "quaternion.h"\r
\r
\r
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),\r
JointMode(EJUOR_NONE), JointsUsed(false),\r
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),\r
- LoopCallBack(0), PassCount(0), Shadow(0), MD3Special(0)\r
+ LoopCallBack(0), PassCount(0)\r
{\r
#ifdef _DEBUG\r
setDebugName("CAnimatedMeshSceneNode");\r
//! destructor\r
CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()\r
{\r
- if (MD3Special)\r
- MD3Special->drop();\r
-\r
- if (Mesh)\r
- Mesh->drop();\r
-\r
- if (Shadow)\r
- Shadow->drop();\r
-\r
if (LoopCallBack)\r
LoopCallBack->drop();\r
}\r
// As multiple scene nodes may be sharing the same skinned mesh, we have to\r
// re-animate it every frame to ensure that this node gets the mesh that it needs.\r
\r
- CSkinnedMesh* skinnedMesh = reinterpret_cast<CSkinnedMesh*>(Mesh);\r
+ CSkinnedMesh* skinnedMesh = static_cast<CSkinnedMesh*>(Mesh);\r
\r
if (JointMode == EJUOR_CONTROL)//write to mesh\r
skinnedMesh->transferJointsToMesh(JointChildSceneNodes);\r
\r
// set CurrentFrameNr\r
buildFrameNr(timeMs-LastTimeMs);\r
-\r
- // update bbox\r
- if (Mesh)\r
- {\r
- scene::IMesh * mesh = getMeshForCurrentFrame();\r
-\r
- if (mesh)\r
- Box = mesh->getBoundingBox();\r
- }\r
LastTimeMs = timeMs;\r
\r
IAnimatedMeshSceneNode::OnAnimate(timeMs);\r
#ifdef _DEBUG\r
os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING);\r
#endif\r
+ return;\r
}\r
\r
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);\r
\r
- if (Shadow && PassCount==1)\r
- Shadow->updateShadowVolumes();\r
-\r
// for debug purposes only:\r
\r
bool renderMeshes = true;\r
// show normals\r
if (DebugDataVisible & scene::EDS_NORMALS)\r
{\r
- const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH);\r
- const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR);\r
+ const f32 debugNormalLength = 1.f;\r
+ const video::SColor debugNormalColor = video::SColor(255, 34, 221, 221);\r
const u32 count = m->getMeshBufferCount();\r
\r
// draw normals\r
}\r
}\r
}\r
-\r
- // show tag for quake3 models\r
- if (Mesh->getMeshType() == EAMT_MD3)\r
- {\r
- IAnimatedMesh * arrow =\r
- SceneManager->addArrowMesh (\r
- "__tag_show",\r
- 0xFF0000FF, 0xFF000088,\r
- 4, 8, 5.f, 4.f, 0.5f,\r
- 1.f);\r
- if (!arrow)\r
- {\r
- arrow = SceneManager->getMesh ( "__tag_show" );\r
- }\r
- IMesh *arrowMesh = arrow->getMesh(0);\r
-\r
- core::matrix4 matr;\r
-\r
- SMD3QuaternionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList(\r
- (s32)getFrameNr(), 255,\r
- getStartFrame(), getEndFrame());\r
- if (taglist)\r
- {\r
- for ( u32 ts = 0; ts != taglist->size(); ++ts )\r
- {\r
- (*taglist)[ts].setto(matr);\r
-\r
- driver->setTransform(video::ETS_WORLD, matr );\r
-\r
- for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a )\r
- driver->drawMeshBuffer(arrowMesh->getMeshBuffer(a));\r
- }\r
- }\r
- }\r
}\r
\r
// show mesh\r
}\r
\r
\r
-//! Creates shadow volume scene node as child of this node\r
-//! and returns a pointer to it.\r
-IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(\r
- const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity)\r
-{\r
-#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_\r
- if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))\r
- return 0;\r
-\r
- if (!shadowMesh)\r
- shadowMesh = Mesh; // if null is given, use the mesh of node\r
-\r
- if (Shadow)\r
- Shadow->drop();\r
-\r
- Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity);\r
- return Shadow;\r
-#else\r
- return 0;\r
-#endif\r
-}\r
-\r
//! Returns a pointer to a child node, which has the same transformation as\r
//! the corresponding joint, if the mesh in this scene node is a skinned mesh.\r
IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName)\r
//! or to remove attached childs.\r
bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child)\r
{\r
- if (child && Shadow == child)\r
- {\r
- Shadow->drop();\r
- Shadow = 0;\r
- }\r
-\r
if (ISceneNode::removeChild(child))\r
{\r
if (JointsUsed) //stop weird bugs caused while changing parents as the joints are being created\r
}\r
\r
\r
-//! Starts a MD2 animation.\r
-bool CAnimatedMeshSceneNode::setMD2Animation(EMD2_ANIMATION_TYPE anim)\r
-{\r
- if (!Mesh || Mesh->getMeshType() != EAMT_MD2)\r
- return false;\r
-\r
- IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh;\r
-\r
- s32 begin, end, speed;\r
- md->getFrameLoop(anim, begin, end, speed);\r
-\r
- setAnimationSpeed( f32(speed) );\r
- setFrameLoop(begin, end);\r
- return true;\r
-}\r
-\r
-\r
-//! Starts a special MD2 animation.\r
-bool CAnimatedMeshSceneNode::setMD2Animation(const c8* animationName)\r
-{\r
- if (!Mesh || Mesh->getMeshType() != EAMT_MD2)\r
- return false;\r
-\r
- IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh;\r
-\r
- s32 begin, end, speed;\r
- if (!md->getFrameLoop(animationName, begin, end, speed))\r
- return false;\r
-\r
- setAnimationSpeed( (f32)speed );\r
- setFrameLoop(begin, end);\r
- return true;\r
-}\r
-\r
-\r
//! Sets looping mode which is on by default. If set to false,\r
//! animations will not be looped.\r
void CAnimatedMeshSceneNode::setLoopMode(bool playAnimationLooped)\r
}\r
\r
\r
-//! Writes attributes of the scene node.\r
-void CAnimatedMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const\r
-{\r
- IAnimatedMeshSceneNode::serializeAttributes(out, options);\r
-\r
- if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename)\r
- {\r
- const io::path path = SceneManager->getFileSystem()->getRelativeFilename(\r
- SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()),\r
- options->Filename);\r
- out->addString("Mesh", path.c_str());\r
- }\r
- else\r
- out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str());\r
- out->addBool("Looping", Looping);\r
- out->addBool("ReadOnlyMaterials", ReadOnlyMaterials);\r
- out->addFloat("FramesPerSecond", FramesPerSecond);\r
- out->addInt("StartFrame", StartFrame);\r
- out->addInt("EndFrame", EndFrame);\r
-}\r
-\r
-\r
-//! Reads attributes of the scene node.\r
-void CAnimatedMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)\r
-{\r
- IAnimatedMeshSceneNode::deserializeAttributes(in, options);\r
-\r
- io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh);\r
- io::path newMeshStr = in->getAttributeAsString("Mesh");\r
-\r
- Looping = in->getAttributeAsBool("Looping");\r
- ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials");\r
- FramesPerSecond = in->getAttributeAsFloat("FramesPerSecond");\r
- StartFrame = in->getAttributeAsInt("StartFrame");\r
- EndFrame = in->getAttributeAsInt("EndFrame");\r
-\r
- if (newMeshStr != "" && oldMeshStr != newMeshStr)\r
- {\r
- IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());\r
-\r
- if (newAnimatedMesh)\r
- setMesh(newAnimatedMesh);\r
- }\r
-\r
- // TODO: read animation names instead of frame begin and ends\r
-}\r
-\r
-\r
//! Sets a new mesh\r
void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh)\r
{\r
}\r
\r
\r
-// returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh,\r
-// or the absolutetransformation if it's a normal scenenode\r
-const SMD3QuaternionTag* CAnimatedMeshSceneNode::getMD3TagTransformation(const core::stringc& tagname)\r
-{\r
- return MD3Special ? MD3Special->AbsoluteTagList.get(tagname) : 0;\r
-}\r
-\r
-\r
//! updates the absolute position based on the relative and the parents position\r
void CAnimatedMeshSceneNode::updateAbsolutePosition()\r
{\r
IAnimatedMeshSceneNode::updateAbsolutePosition();\r
-\r
- if (!Mesh || Mesh->getMeshType() != EAMT_MD3)\r
- return;\r
-\r
- SMD3QuaternionTagList *taglist;\r
- taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( (s32)getFrameNr(),255,getStartFrame (),getEndFrame () );\r
- if (taglist)\r
- {\r
- if (!MD3Special)\r
- {\r
- MD3Special = new SMD3Special();\r
- }\r
-\r
- SMD3QuaternionTag parent ( MD3Special->Tagname );\r
- if (Parent && Parent->getType() == ESNT_ANIMATED_MESH)\r
- {\r
- const SMD3QuaternionTag * p = ((IAnimatedMeshSceneNode*) Parent)->getMD3TagTransformation\r
- ( MD3Special->Tagname );\r
-\r
- if (p)\r
- parent = *p;\r
- }\r
-\r
- SMD3QuaternionTag relative( RelativeTranslation, RelativeRotation );\r
-\r
- MD3Special->AbsoluteTagList.set_used ( taglist->size () );\r
- for ( u32 i=0; i!= taglist->size (); ++i )\r
- {\r
- MD3Special->AbsoluteTagList[i].position = parent.position + (*taglist)[i].position + relative.position;\r
- MD3Special->AbsoluteTagList[i].rotation = parent.rotation * (*taglist)[i].rotation * relative.rotation;\r
- }\r
- }\r
}\r
\r
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)\r
checkJoints();\r
const f32 frame = getFrameNr(); //old?\r
\r
- CSkinnedMesh* skinnedMesh=reinterpret_cast<CSkinnedMesh*>(Mesh);\r
+ CSkinnedMesh* skinnedMesh=static_cast<CSkinnedMesh*>(Mesh);\r
\r
skinnedMesh->transferOnlyJointsHintsToMesh( JointChildSceneNodes );\r
skinnedMesh->animateMesh(frame, 1.0f);\r
if (newNode->LoopCallBack)\r
newNode->LoopCallBack->grab();\r
newNode->PassCount = PassCount;\r
- newNode->Shadow = Shadow;\r
- if (newNode->Shadow)\r
- newNode->Shadow->grab();\r
newNode->JointChildSceneNodes = JointChildSceneNodes;\r
newNode->PretransitingSave = PretransitingSave;\r
newNode->RenderFromIdentity = RenderFromIdentity;\r
- newNode->MD3Special = MD3Special;\r
\r
return newNode;\r
}\r