Merged SkinnedMesh branch 658:895 into trunk.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@896 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2007-09-04 18:51:42 +00:00
parent f3a8858e09
commit bda0b6e35f
56 changed files with 7621 additions and 7720 deletions

View File

@ -7,12 +7,12 @@
#include "IUnknown.h"
#include "aabbox3d.h"
#include "IMesh.h"
namespace irr
{
namespace scene
{
class IMesh;
enum E_ANIMATED_MESH_TYPE
{
@ -20,10 +20,10 @@ namespace scene
EAMT_UNKNOWN = 0,
//! Quake 2 MD2 model file
EAMT_MD2,
EAMT_MD2,
//! Quake 3 MD3 model file
EAMT_MD3,
EAMT_MD3,
//! Milkshape 3d skeletal animation file
EAMT_MS3D,
@ -37,8 +37,8 @@ namespace scene
//! 3D Studio .3ds file
EAMT_3DS,
//! Microsoft Direct3D .x-file. Can contain static and skeletal animated
//! skinned meshes. This is the standard and best supported
//! Microsoft Direct3D .x-file. Can contain static and skeletal animated
//! skinned meshes. This is the standard and best supported
//! format of the Irrlicht Engine.
EAMT_X,
@ -53,20 +53,20 @@ namespace scene
EAMT_CSM,
//! .oct file for Paul Nette's FSRad or from Murphy McCauley's Blender .oct exporter.
//! The oct file format contains 3D geometry and lightmaps and can
//! The oct file format contains 3D geometry and lightmaps and can
//! be loaded directly by Irrlicht
EAMT_OCT,
//! Blitz Basic .b3d file, the file format by Mark Sibly
EAMT_B3D
//! genetic skinned mesh
EAMT_SKINNED
};
//! Interface for an animated mesh.
/** There are already simple implementations of this interface available so
/** There are already simple implementations of this interface available so
you don't have to implement this interface on your own if you need to:
You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh,
You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh,
irr::scene::SMeshBuffer etc. */
class IAnimatedMesh : public virtual IUnknown
class IAnimatedMesh : public IMesh
{
public:
@ -86,7 +86,7 @@ namespace scene
\param startFrameLoop: Because some animated meshes (.MD2) are blended between 2
static frames, and maybe animated in a loop, the startFrameLoop and the endFrameLoop
have to be defined, to prevent the animation to be blended between frames which are
outside of this loop.
outside of this loop.
If startFrameLoop and endFrameLoop are both -1, they are ignored.
\param endFrameLoop: see startFrameLoop.
\return Returns the animated mesh based on a detail level. */

View File

@ -1,100 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_ANIMATED_MESH_B3D_H_INCLUDED__
#define __I_ANIMATED_MESH_B3D_H_INCLUDED__
#include "IAnimatedMesh.h"
#include "irrArray.h"
#include "matrix4.h"
namespace irr
{
namespace scene
{
class ISceneNode;
class ISceneManager;
//! Interface for using some special functions of B3d meshes
/** Please note that the B3d Mesh's frame numbers are scaled by 100 */
class IAnimatedMeshB3d : public IAnimatedMesh
{
public:
//! Returns a pointer to a transformation matrix of a part of the
//! mesh based on a frame time. This is used for being able to attach
//! objects to parts of animated meshes. For example a weapon to an animated
//! hand.
//! \param jointNumber: Zero based index of joint. The last joint has the number
//! IAnimatedMeshB3d::getJointCount()-1;
//! \param frame: Frame of the animation.
//! \return Returns a pointer to the matrix of the mesh part or
//! null if an error occured.
virtual core::matrix4* getMatrixOfJoint(s32 jointNumber, s32 frame) = 0;
//! Returns a pointer to a local matrix of a Joint, can be used to control the animation
virtual core::matrix4* getLocalMatrixOfJoint(s32 jointNumber) = 0;
//! Returns a pointer to a matrix of a part of the mesh unanimated
virtual core::matrix4* getMatrixOfJointUnanimated(s32 jointNumber) = 0;
//! Move this Joint's local matrix when animating
//! \param jointNumber: Zero based index of joint. The last joint has the number
//! IAnimatedMeshB3d::getJointCount()-1;
//! \param On: False= Leave joint's local matrix, True= Animate
//! (not used yet)
virtual void setJointAnimation(s32 jointNumber, bool On) = 0;
//! Gets joint count.
//! \return Returns amount of joints in the skeletal animated mesh.
virtual s32 getJointCount() const = 0;
//! Gets the name of a joint.
//! \param number: Zero based index of joint. The last joint has the number
//! IAnimatedMeshB3d::getJointCount()-1;
//! \return Returns name of joint and null if an error happened.
virtual const c8* getJointName(s32 number) const = 0;
//! Gets a joint number from its name
//! \param name: Name of the joint.
//! \return Returns the number of the joint or -1 if not found.
virtual s32 getJointNumber(const c8* name) const = 0;
//!Update Normals when Animating
//!False= Don't (default)
//!True= Update normals, slower
virtual void updateNormalsWhenAnimating(bool on) = 0;
//!Sets Interpolation Mode
//!0- Constant
//!1- Linear (default)
virtual void setInterpolationMode(s32 mode) = 0;
//!Want should happen on when animating
//!0-Nothing
//!1-Update nodes only
//!2-Update skin only
//!3-Update both nodes and skin (default)
virtual void setAnimateMode(s32 mode) = 0;
//!Convert all mesh buffers to use tangent vertices
virtual void convertToTangents() =0;
virtual void recoverJointsFromMesh(core::array<ISceneNode*> &JointChildSceneNodes)=0;
virtual void tranferJointsToMesh(core::array<ISceneNode*> &JointChildSceneNodes)=0;
virtual void createJoints(core::array<ISceneNode*> &JointChildSceneNodes, ISceneNode* AnimatedMeshSceneNode, ISceneManager* SceneManager)=0;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -1,52 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt / Fabio Concas / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_ANIMATED_MESH_MS3D_H_INCLUDED__
#define __I_ANIMATED_MESH_MS3D_H_INCLUDED__
#include "IAnimatedMesh.h"
#include "matrix4.h"
namespace irr
{
namespace scene
{
//! Interface for using some special functions of MS3D meshes
class IAnimatedMeshMS3D : public IAnimatedMesh
{
public:
//! Returns a pointer to a transformation matrix of a part of the
//! mesh based on a frame time. This is used for being able to attach
//! objects to parts of animated meshes. For example a weapon to an animated
//! hand.
//! \param jointNumber: Zero based index of joint. The last joint has the number
//! IAnimatedMeshMS3D::getJointCount()-1;
//! \param frame: Frame of the animation.
//! \return Returns a pointer to the matrix of the mesh part or
//! null if an error occured.
virtual core::matrix4* getMatrixOfJoint(s32 jointNumber, s32 frame) = 0;
//! Gets joint count.
//! \return Returns amount of joints in the skeletal animated mesh.
virtual s32 getJointCount() const = 0;
//! Gets the name of a joint.
//! \param number: Zero based index of joint. The last joint has the number
//! IAnimatedMeshMS3D::getJointCount()-1;
//! \return Returns name of joint and null if an error happened.
virtual const c8* getJointName(s32 number) const = 0;
//! Gets a joint number from its name
//! \param name: Name of the joint.
//! \return Returns the number of the joint or -1 if not found.
virtual s32 getJointNumber(const c8* name) const = 0;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -6,6 +6,7 @@
#define __I_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__
#include "ISceneNode.h"
#include "IBoneSceneNode.h"
#include "IAnimatedMeshMD2.h"
#include "IAnimatedMeshMD3.h"
#include "IShadowVolumeSceneNode.h"
@ -54,7 +55,7 @@ namespace scene
//! \param frame: Number of the frame to let the animation be started from.
//! The frame number must be a valid frame number of the IMesh used by this
//! scene node. Set IAnimatedMesh::getMesh() for details.
virtual void setCurrentFrame(s32 frame) = 0;
virtual void setCurrentFrame(f32 frame) = 0;
//! Sets the frame numbers between the animation is looped.
//! The default is 0 - MaximalFrameCount of the mesh.
@ -84,6 +85,26 @@ namespace scene
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id=-1,
bool zfailmethod=true, f32 infinity=10000.0f) = 0;
//! Returns a pointer to a child node, which has the same transformation as
//! the corresponding joint, if the mesh in this scene node is a ms3d mesh.
//! Otherwise 0 is returned. With this method it is possible to
//! attach scene nodes to joints more easily. In this way, it is
//! for example possible to attach a weapon to the left hand of an
//! animated model. This example shows how:
//! \code
//! ISceneNode* hand =
//! yourAnimatedMeshSceneNode->getJointNode("LeftHand");
//! hand->addChild(weaponSceneNode);
//! \endcode
//! Please note that the SceneNode returned by this method may not exist
//! before this call and is created by it. (Todo: Rewrite)
//! \param jointName: Name of the joint.
//! \return Returns a pointer to the scene node which represents the joint
//! with the specified name. Returns 0 if the contained mesh is not an
//! ms3d mesh or the name of the joint could not be found.
virtual IBoneSceneNode* getJointNode(const c8* jointName)=0;
//! Returns a pointer to a child node, which has the same transformation as
//! the corresponding joint, if the mesh in this scene node is a ms3d mesh.
//! Otherwise 0 is returned. With this method it is possible to
@ -122,25 +143,6 @@ namespace scene
//! ms3d mesh or the name of the joint could not be found.
virtual ISceneNode* getXJointNode(const c8* jointName) = 0;
//! Returns a pointer to a child node, which has the same transformation as
//! the corresponding joint, if the mesh in this scene node is a b3d mesh.
//! Otherwise 0 is returned. With this method it is possible to
//! attach scene nodes to joints more easily. In this way, it is
//! for example possible to attach a weapon to the left hand of an
//! animated model. This example shows how:
//! \code
//! ISceneNode* hand =
//! yourB3DAnimatedMeshSceneNode->getB3DJointNode("LeftHand");
//! hand->addChild(weaponSceneNode);
//! \endcode
//! Please note that the SceneNode returned by this method may not exist
//! before this call and is created by it.
//! \param jointName: Name of the joint.
//! \return Returns a pointer to the scene node which represents the joint
//! with the specified name. Returns 0 if the contained mesh is not an
//! ms3d mesh or the name of the joint could not be found.
virtual ISceneNode* getB3DJointNode(const c8* jointName) = 0;
//! Starts a default MD2 animation.
//! With this method it is easily possible to start a Run, Attack,
//! Die or whatever animation, if the mesh contained in this scene
@ -165,7 +167,7 @@ namespace scene
virtual bool setMD2Animation(const c8* animationName) = 0;
//! Returns the current displayed frame number.
virtual s32 getFrameNr() const = 0;
virtual f32 getFrameNr() const = 0;
//! Returns the current start frame number.
virtual s32 getStartFrame() const = 0;
//! Returns the current end frame number.
@ -199,6 +201,16 @@ namespace scene
// or the absolutetransformation if it's a normal scenenode
virtual const SMD3QuaterionTag& getMD3TagTransformation( const core::stringc & tagname) = 0;
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
virtual void setJointMode(s32 mode)=0;
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
virtual void setTransitionTime(f32 Time) =0;
//! updates the joint positions of this mesh
virtual void animateJoints() = 0;
};
} // end namespace scene

View File

@ -1,81 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_ANIMATED_MESH_X_H_INCLUDED__
#define __I_ANIMATED_MESH_X_H_INCLUDED__
#include "IAnimatedMesh.h"
#include "irrArray.h"
#include "matrix4.h"
namespace irr
{
namespace scene
{
//! Interface for using some special functions of X meshes
class IAnimatedMeshX : public IAnimatedMesh
{
public:
//! Returns a pointer to a transformation matrix of a part of the
//! mesh based on a frame time. This is used for being able to attach
//! objects to parts of animated meshes. For example a weapon to an animated
//! hand.
//! \param jointNumber: Zero based index of joint. The last joint has the number
//! IAnimatedMeshX::getJointCount()-1;
//! \param frame: Frame of the animation.
//! \return Returns a pointer to the matrix of the mesh part or
//! null if an error occured.
virtual core::matrix4* getMatrixOfJoint(s32 jointNumber, s32 frame) = 0;
//! Gets joint count.
//! \return Returns amount of joints in the skeletal animated mesh.
virtual s32 getJointCount() const = 0;
//! Gets the name of a joint.
//! \param number: Zero based index of joint. The last joint has the number
//! IAnimatedMeshX::getJointCount()-1;
//! \return Returns name of joint and null if an error happened.
virtual const c8* getJointName(s32 number) const = 0;
//! Gets a joint number from its name
//! \param name: Name of the joint.
//! \return Returns the number of the joint or -1 if not found.
virtual s32 getJointNumber(const c8* name) const = 0;
//! Returns a pointer to list of points containing the skeleton.
//! Draw a line between point 1 and 2, and 3 and 4 and 5 and 6
//! and so on to visualize this. Only for debug purposes. If you
//! use an .x-File with the IAnimatedMeshSceneNode and turn DebugDataVisible
//! to true, the Scene node will visualize the skeleton using this
//! method.
virtual const core::array<core::vector3df>* getDrawableSkeleton(s32 frame) = 0;
//! Returns amount of animations in .X-file.
virtual s32 getAnimationCount() const = 0;
//! Returns the name of an animation.
//! \param idx: Zero based Index of the animation. Must be a value between
//! 0 and getAnimationCount()-1;
//! \return Returns pointer to the string of the name of the animation.
//! Returns 0 if an animation with this index does not exist.
virtual const c8* getAnimationName(s32 idx) const = 0;
//! Sets an animation as animation to play back.
//! \param idx: Zero based Index of the animation. Must be a value between
//! 0 and getAnimationCount()-1;
virtual void setCurrentAnimation(s32 idx) = 0;
//! Sets an animation as animation to play back.
//! \param name: Name of the animtion.
//! \return Returns true if successful, and false if the specified animation
//! does not exist.
virtual bool setCurrentAnimation(const c8* name) = 0;
};
} // end namespace scene
} // end namespace irr
#endif

97
include/IBoneSceneNode.h Normal file
View File

@ -0,0 +1,97 @@
#ifndef __I_BONE_SCENE_NODE_H_INCLUDED__
#define __I_BONE_SCENE_NODE_H_INCLUDED__
// Used with SkinnedMesh and IAnimatedMeshSceneNode, for boned meshes
#include "ISceneNode.h"
namespace irr
{
namespace scene
{
//! Enumeration for different bone animation modes
enum E_BONE_ANIMATION_MODE
{
//! The bone is usually animated, unless it's parent is not animated
EBAM_AUTOMATIC=0,
//! The bone is animated by the skin, if it's parent is not animated
//! then animation will resume from this bone onward
EBAM_ANIMATED,
//! The bone is not animated by the skin
EBAM_UNANIMATED,
//! Not an animation mode, just here to count the available modes
EBAM_COUNT
};
//! Names for bone animation modes
const c8* const BoneAnimationModeNames[] =
{
"automatic",
"animated",
"unanimated",
0,
};
class IBoneSceneNode : public ISceneNode
{
public:
IBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1) :
ISceneNode(parent, mgr, id),positionHint(-1),scaleHint(-1),rotationHint(-1) { }
//! Returns the name of the bone
virtual const c8* getBoneName() const = 0;
//! Returns the index of the bone
virtual u32 getBoneIndex() const = 0;
//! Sets the animation mode of the bone. Returns true if successful.
virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode) = 0;
//! Gets the current animation mode of the bone
virtual E_BONE_ANIMATION_MODE getAnimationMode() const = 0;
//! returns the axis aligned bounding box of this node
virtual const core::aabbox3d<f32>& getBoundingBox() const = 0;
//! Returns the relative transformation of the scene node.
//virtual core::matrix4 getRelativeTransformation() const = 0;
virtual void OnAnimate(u32 timeMs) =0;
//! Does nothing as bones are not visible
virtual void render() { };
virtual void setAbsoluteTransformation(core::matrix4 transformation)
{
AbsoluteTransformation=transformation;
}
//! updates the absolute position based on the relative and the parents position
virtual void updateAbsolutePositionOfAllChildren()=0;
s32 positionHint;
s32 scaleHint;
s32 rotationHint;
};
} // end namespace scene
} // end namespace irr
#endif

215
include/ISkinnedMesh.h Normal file
View File

@ -0,0 +1,215 @@
// Copyright (C) 2002-2006 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_SKINNED_MESH_H_INCLUDED__
#define __I_SKINNED_MESH_H_INCLUDED__
#include "irrArray.h"
#include "IBoneSceneNode.h"
#include "IAnimatedMesh.h"
#include "SSkinMeshBuffer.h"
namespace irr
{
namespace scene
{
enum E_INTERPOLATION_MODE
{
// constant interpolation
EIM_CONSTANT = 0,
// linear interpolation
EIM_LINEAR,
//! count of all available interpolation modes
EIM_COUNT
};
//! Interface for using some special functions of Skinned meshes
class ISkinnedMesh : public IAnimatedMesh
{
public:
//! Gets joint count.
//! \return Returns amount of joints in the skeletal animated mesh.
virtual s32 getJointCount() const = 0;
//! Gets the name of a joint.
//! \param number: Zero based index of joint. The last joint has the number
//! IAnimatedMeshB3d::getJointCount()-1;
//! \return Returns name of joint and null if an error happened.
virtual const c8* getJointName(s32 number) const = 0;
//! Gets a joint number from its name
//! \param name: Name of the joint.
//! \return Returns the number of the joint or -1 if not found.
virtual s32 getJointNumber(const c8* name) const = 0;
//! uses animation from another mesh
//! the animation is linked (not copied) based on joint names (so make sure they are unique)
//! \return Returns true if all joints in this mesh were matched up (empty names will not be matched, and it's case sensitive)
//! unmatched joints will not be animated
virtual bool useAnimationFrom(ISkinnedMesh *mesh) = 0;
//!Update Normals when Animating
//!False= Don't (default)
//!True= Update normals, slower
virtual void updateNormalsWhenAnimating(bool on) = 0;
//!Sets Interpolation Mode
virtual void setInterpolationMode(E_INTERPOLATION_MODE mode) = 0;
//! Animates this mesh's joints based on frame input
virtual void animateMesh(f32 frame, f32 blend)=0;
//! Preforms a software skin on this mesh based of joint positions
virtual void skinMesh() = 0;
//!Recovers the joints from the mesh
virtual void recoverJointsFromMesh(core::array<IBoneSceneNode*> &JointChildSceneNodes) = 0;
//!Tranfers the joint data to the mesh
virtual void tranferJointsToMesh(core::array<IBoneSceneNode*> &JointChildSceneNodes) = 0;
//!Creates an array of joints from this mesh
virtual void createJoints(core::array<IBoneSceneNode*> &JointChildSceneNodes,
IAnimatedMeshSceneNode* AnimatedMeshSceneNode, ISceneManager* SceneManager) = 0;
virtual void convertMeshToTangents() = 0;
//! A vertex weight
struct SWeight
{
//! Index of the mesh buffer
u16 buffer_id; //I doubt 32bits is needed
//! Index of the vertex
u32 vertex_id; //Store global ID here
//! Weight Strength/Percentage (0-1)
f32 strength;
private:
//! Internal members used by CSkinnedMesh
friend class CSkinnedMesh;
bool *Moved;
core::vector3df StaticPos;
core::vector3df StaticNormal;
};
//! Animation keyframe which describes a new position, scale or rotation
struct SPositionKey
{
f32 frame;
core::vector3df position;
};
struct SScaleKey
{
f32 frame;
core::vector3df scale;
};
struct SRotationKey
{
f32 frame;
core::quaternion rotation;
};
//! Joints
struct SJoint
{
SJoint() :
Name(""), LocalMatrix(),
Children(), PositionKeys(), ScaleKeys(), RotationKeys(), Weights(),
UseAnimationFrom(0), LocalAnimatedMatrix_Animated(false),positionHint(-1),scaleHint(-1),rotationHint(-1)
{
}
//! The name of this joint
core::stringc Name;
//! Local matrix of this joint
core::matrix4 LocalMatrix;
//! List of child joints
core::array<SJoint*> Children;
//! Animation keys causing translation change
core::array<SPositionKey> PositionKeys;
//! Animation keys causing scale change
core::array<SScaleKey> ScaleKeys;
//! Animation keys causing rotation change
core::array<SRotationKey> RotationKeys;
//! Skin weights
core::array<SWeight> Weights;
//! Unnecessary for loaders, will be overwritten on finalize
core::matrix4 GlobalMatrix;
core::matrix4 GlobalAnimatedMatrix;
core::matrix4 LocalAnimatedMatrix;
core::vector3df Animatedposition;
core::vector3df Animatedscale;
core::quaternion Animatedrotation;
core::matrix4 GlobalInversedMatrix; //the x format pre-calculates this
private:
//! Internal members used by CSkinnedMesh
friend class CSkinnedMesh;
SJoint *UseAnimationFrom;
bool LocalAnimatedMatrix_Animated;
s32 positionHint;
s32 scaleHint;
s32 rotationHint;
};
//Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_
//these functions will use the needed arrays, set vaules, etc to help the loaders
//! exposed for loaders to add mesh buffers
virtual core::array<SSkinMeshBuffer*> &getMeshBuffers() = 0;
//! alternative method for adding joints
virtual core::array<SJoint*> &getAllJoints() = 0;
//! loaders should call this after populating the mesh
virtual void finalize() = 0;
virtual SSkinMeshBuffer *createBuffer() = 0;
virtual SJoint *createJoint(SJoint *parent=0) = 0;
virtual SPositionKey *createPositionKey(SJoint *joint) = 0;
virtual SScaleKey *createScaleKey(SJoint *joint) = 0;
virtual SRotationKey *createRotationKey(SJoint *joint) = 0;
virtual SWeight *createWeight(SJoint *joint) = 0;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -6,7 +6,7 @@
#define __IRR_COMPILE_CONFIG_H_INCLUDED__
//! Irrlicht SDK Version
#define IRRLICHT_SDK_VERSION "1.3.1"
#define IRRLICHT_SDK_VERSION "1.4RC"
//! The defines for different operating system are:
//! _IRR_XBOX_PLATFORM_ for XBox
@ -213,6 +213,46 @@ Note that the engine will run in D3D REF for this, which is a lot slower than HA
//#define BURNINGVIDEO_RENDERER_ULTRA_FAST
//! Define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ if you want to use bone based
/** animated meshes. If you compile without this, you will be unable to load
B3D, MS3D or X meshes */
#define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to use Blitz3D files
#define _IRR_COMPILE_WITH_B3D_LOADER_
//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to Milkshape files
#define _IRR_COMPILE_WITH_MS3D_LOADER_
//! Define _IRR_COMPILE_WITH_X_LOADER_ if you want to use Microsoft X files
#define _IRR_COMPILE_WITH_X_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_MD2_LOADER_ if you want to load Quake 2 animated files
#define _IRR_COMPILE_WITH_MD2_LOADER_
//! Define _IRR_COMPILE_WITH_MD3_LOADER_ if you want to load Quake 3 animated files
#define _IRR_COMPILE_WITH_MD3_LOADER_
//! Define _IRR_COMPILE_WITH_3DS_LOADER_ if you want to load 3D Studio Max files
#define _IRR_COMPILE_WITH_3DS_LOADER_
//! Define _IRR_COMPILE_WITH_COLLADA_LOADER_ if you want to load Collada files
#define _IRR_COMPILE_WITH_COLLADA_LOADER_
//! Define _IRR_COMPILE_WITH_CSM_LOADER_ if you want to load Cartography Shop files
#define _IRR_COMPILE_WITH_CSM_LOADER_
//! Define _IRR_COMPILE_WITH_BSP_LOADER_ if you want to load Quake 3 BSP files
#define _IRR_COMPILE_WITH_BSP_LOADER_
//! Define _IRR_COMPILE_WITH_DMF_LOADER_ if you want to load DeleD files
#define _IRR_COMPILE_WITH_DMF_LOADER_
//! Define _IRR_COMPILE_WITH_LMTS_LOADER_ if you want to load LMTools files
#define _IRR_COMPILE_WITH_LMTS_LOADER_
//! Define _IRR_COMPILE_WITH_MY3D_LOADER_ if you want to load MY3D files
#define _IRR_COMPILE_WITH_MY3D_LOADER_
//! Define _IRR_COMPILE_WITH_OBJ_LOADER_ if you want to load Wavefront OBJ files
#define _IRR_COMPILE_WITH_OBJ_LOADER_
//! Define _IRR_COMPILE_WITH_OCT_LOADER_ if you want to load FSRad OCT files
#define _IRR_COMPILE_WITH_OCT_LOADER_
//! Define _IRR_COMPILE_WITH_OGRE_LOADER_ if you want to load Ogre 3D files
#define _IRR_COMPILE_WITH_OGRE_LOADER_
//! Set FPU settings
/** Irrlicht should use approximate float and integer fpu techniques
precision will be lower but speed higher. currently X86 only

View File

@ -63,7 +63,7 @@ namespace scene
//! 255 the highest level of detail. Most meshes will ignore the detail level.
//! \param startFrameLoop: start frame
//! \param endFrameLoop: end frame
//! \return Returns the animated mesh based on a detail level.
//! \return Returns the animated mesh based on a detail level.
virtual IMesh* getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop=-1, s32 endFrameLoop=-1)
{
if (Meshes.empty())
@ -83,7 +83,7 @@ namespace scene
}
}
//! Returns an axis aligned bounding box of the mesh.
//! \return A bounding box of this mesh is returned.
virtual const core::aabbox3d<f32>& getBoundingBox() const
@ -107,16 +107,42 @@ namespace scene
Box = Meshes[0]->getBoundingBox();
for (u32 i=1; i<Meshes.size(); ++i)
Box.addInternalBox(Meshes[i]->getBoundingBox());
Box.addInternalBox(Meshes[i]->getBoundingBox());
}
//! Returns the type of the animated mesh.
virtual E_ANIMATED_MESH_TYPE getMeshType() const
{
return Type;
}
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const
{
return 0;
}
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const
{
return 0;
}
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const
{
return 0;
}
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{
return;
}
core::aabbox3d<f32> Box;
core::array<IMesh*> Meshes;
E_ANIMATED_MESH_TYPE Type;

232
include/SSkinMeshBuffer.h Normal file
View File

@ -0,0 +1,232 @@
// Copyright (C) 2002-2006 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_SKIN_MESH_BUFFER_H_INCLUDED__
#define __I_SKIN_MESH_BUFFER_H_INCLUDED__
#include "IMeshBuffer.h"
#include "S3DVertex.h"
namespace irr
{
namespace scene
{
//! A mesh buffer able to choose between
//! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
struct SSkinMeshBuffer : public IMeshBuffer
{
SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) : VertexType(vt)
{
#ifdef _DEBUG
setDebugName("SSkinMeshBuffer");
#endif
}
virtual ~SSkinMeshBuffer() {}
virtual const video::SMaterial& getMaterial() const
{
return Material;
}
virtual video::SMaterial& getMaterial()
{
return Material;
}
virtual video::S3DVertex *getVertex(u32 index)
{
switch (VertexType)
{
case video::EVT_2TCOORDS: return (video::S3DVertex*)&Vertices_2TCoords[index];
case video::EVT_TANGENTS: return (video::S3DVertex*)&Vertices_Tangents[index];
default: return &Vertices_Standard[index];
}
}
virtual const void* getVertices() const
{
switch (VertexType)
{
case video::EVT_2TCOORDS: return Vertices_2TCoords.const_pointer();
case video::EVT_TANGENTS: return Vertices_Tangents.const_pointer();
default: return Vertices_Standard.const_pointer();
}
}
virtual void* getVertices()
{
switch (VertexType)
{
case video::EVT_2TCOORDS: return Vertices_2TCoords.pointer();
case video::EVT_TANGENTS: return Vertices_Tangents.pointer();
default: return Vertices_Standard.pointer();
}
}
virtual u32 getVertexCount() const
{
switch (VertexType)
{
case video::EVT_2TCOORDS: return Vertices_2TCoords.size();
case video::EVT_TANGENTS: return Vertices_Tangents.size();
default: return Vertices_Standard.size();
}
}
virtual const u16* getIndices() const
{
return Indices.const_pointer();
}
virtual u16* getIndices()
{
return Indices.pointer();
}
virtual u32 getIndexCount() const
{
return Indices.size();
}
virtual const core::aabbox3d<f32>& getBoundingBox() const
{
return BoundingBox;
}
virtual void setBoundingBox( const core::aabbox3df& box)
{
BoundingBox = box;
}
virtual void recalculateBoundingBox()
{
switch (VertexType)
{
case video::EVT_STANDARD:
{
if (Vertices_Standard.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_Standard[0].Pos);
for (u32 i=1; i<Vertices_Standard.size(); ++i)
BoundingBox.addInternalPoint(Vertices_Standard[i].Pos);
}
break;
}
case video::EVT_2TCOORDS:
{
if (Vertices_2TCoords.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_2TCoords[0].Pos);
for (u32 i=1; i<Vertices_2TCoords.size(); ++i)
BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos);
}
break;
}
case video::EVT_TANGENTS:
{
if (Vertices_Tangents.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_Tangents[0].Pos);
for (u32 i=1; i<Vertices_Tangents.size(); ++i)
BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos);
}
break;
}
}
}
virtual video::E_VERTEX_TYPE getVertexType() const
{
return VertexType;
}
//! returns the byte size (stride, pitch) of the vertex
virtual u32 getVertexPitch() const
{
switch (VertexType)
{
case video::EVT_2TCOORDS: return sizeof(video::S3DVertex2TCoords);
case video::EVT_TANGENTS: return sizeof(video::S3DVertexTangents);
default: return sizeof(video::S3DVertex);
}
}
virtual void MoveTo_2TCoords()
{
if (VertexType==video::EVT_STANDARD)
{
for(u32 n=0;n<Vertices_Standard.size();++n)
{
video::S3DVertex2TCoords Vertex;
Vertex.Color=Vertices_Standard[n].Color;
Vertex.Pos=Vertices_Standard[n].Pos;
Vertex.Normal=Vertices_Standard[n].Normal;
Vertex.TCoords=Vertices_Standard[n].TCoords;
Vertices_2TCoords.push_back(Vertex);
}
Vertices_Standard.clear();
VertexType=video::EVT_2TCOORDS;
}
}
virtual void MoveTo_Tangents()
{
if (VertexType==video::EVT_STANDARD)
{
for(u32 n=0;n<Vertices_Standard.size();++n)
{
video::S3DVertexTangents Vertex;
Vertex.Color=Vertices_Standard[n].Color;
Vertex.Pos=Vertices_Standard[n].Pos;
Vertex.Normal=Vertices_Standard[n].Normal;
Vertex.TCoords=Vertices_Standard[n].TCoords;
Vertices_Tangents.push_back(Vertex);
}
Vertices_Standard.clear();
VertexType=video::EVT_TANGENTS;
}
else if (VertexType==video::EVT_2TCOORDS)
{
for(u32 n=0;n<Vertices_2TCoords.size();++n)
{
video::S3DVertexTangents Vertex;
Vertex.Color=Vertices_2TCoords[n].Color;
Vertex.Pos=Vertices_2TCoords[n].Pos;
Vertex.Normal=Vertices_2TCoords[n].Normal;
Vertex.TCoords=Vertices_2TCoords[n].TCoords;
Vertices_Tangents.push_back(Vertex);
}
Vertices_2TCoords.clear();
VertexType=video::EVT_TANGENTS;
}
}
//! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {}
//! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) {}
video::SMaterial Material;
video::E_VERTEX_TYPE VertexType;
core::array<video::S3DVertexTangents> Vertices_Tangents;
core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
core::array<video::S3DVertex> Vertices_Standard;
core::array<u16> Indices;
core::aabbox3d<f32> BoundingBox;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -18,11 +18,11 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Please note that the Irrlicht Engine is based in part on the work of the
Please note that the Irrlicht Engine is based in part on the work of the
Independent JPEG Group, the zlib and the libPng. This means that if you use
the Irrlicht Engine in your product, you must acknowledge somewhere in your
documentation that you've used the IJG code. It would also be nice to mention
that you use the Irrlicht Engine, the zlib and libPng. See the README files
that you use the Irrlicht Engine, the zlib and libPng. See the README files
in the jpeglib, the zlib and libPng for further informations.
*/
@ -43,13 +43,10 @@
#include "IAnimatedMesh.h"
#include "IAnimatedMeshMD2.h"
#include "IAnimatedMeshMD3.h"
#include "IAnimatedMeshMS3D.h"
#include "IAnimatedMeshMS3D.h"
#include "IQ3LevelMesh.h"
#include "IAnimatedMeshX.h"
#include "IAnimatedMeshB3d.h"
#include "IAnimatedMeshSceneNode.h"
#include "IBillboardSceneNode.h"
#include "IBoneSceneNode.h"
#include "ICameraSceneNode.h"
#include "IDummyTransformationSceneNode.h"
#include "IEventReceiver.h"
@ -104,6 +101,7 @@
#include "ISceneNodeAnimatorCollisionResponse.h"
#include "IShaderConstantSetCallBack.h"
#include "IParticleSystemSceneNode.h" // also includes all emitters and attractors
#include "ISkinnedMesh.h"
#include "ITerrainSceneNode.h"
#include "ITextSceneNode.h"
#include "ITexture.h"
@ -147,8 +145,8 @@
* Welcome to the Irrlicht Engine API documentation.
* Here you'll find any information you'll need to develop applications with
* the Irrlicht Engine. If you are looking for a tutorial on how to start, you'll
* find some on the homepage of the Irrlicht Engine at
* <A HREF="http://irrlicht.sourceforge.net" >irrlicht.sourceforge.net</A>
* find some on the homepage of the Irrlicht Engine at
* <A HREF="http://irrlicht.sourceforge.net" >irrlicht.sourceforge.net</A>
* or inside the SDK in the examples directory.
*
* The Irrlicht Engine is intended to be an easy-to-use 3d engine, so
@ -166,7 +164,7 @@
*
* \section irrexample Short example
*
* A simple application, starting up the engine, loading a Quake 2 animated
* A simple application, starting up the engine, loading a Quake 2 animated
* model file and the corresponding texture, animating and displaying it
* in front of a blue background and placing a user controlable 3d camera
* would look like the following code. I think this example shows the usage
@ -200,7 +198,7 @@
*
* // add a first person shooter style user controlled camera
* scenemgr->addCameraSceneNodeFPS();
*
*
* // draw everything
* while(device->run() && driver)
* {
@ -231,10 +229,10 @@
*
* As you can see, the engine uses namespaces. Everything in the engine is
* placed into the namespace 'irr', but there are also 5 sub namespaces.
* You can find a list of all namespaces with descriptions at the
* <A HREF="namespaces.html"> namespaces page</A>.
* You can find a list of all namespaces with descriptions at the
* <A HREF="namespaces.html"> namespaces page</A>.
* This is also a good place to start reading the documentation. If you
* don't want to write the namespace names all the time, just use all namespaces like
* don't want to write the namespace names all the time, just use all namespaces like
* this:
* \code
* using namespace core;
@ -257,7 +255,7 @@ namespace irr
//! Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.
/** If you need more parameters to be passed to the creation of the Irrlicht Engine device,
use the createDeviceEx() function.
\param deviceType: Type of the device. This can currently be video::EDT_NULL,
\param deviceType: Type of the device. This can currently be video::EDT_NULL,
video::EDT_SOFTWARE, video::EDT_BURNINGSVIDEO, video::EDT_DIRECT3D8, video::EDT_DIRECT3D9 and video::EDT_OPENGL.
\param windowSize: Size of the window or the video mode in fullscreen mode.
\param bits: Bits per pixel in fullscreen mode. Ignored if windowed mode.
@ -266,7 +264,7 @@ namespace irr
\param stencilbuffer: Specifies if the stencil buffer should be enabled. Set this to true,
if you want the engine be able to draw stencil buffer shadows. Note that not all
devices are able to use the stencil buffer. If they don't no shadows will be drawn.
\param vsync: Specifies vertical syncronisation: If set to true, the driver will wait
\param vsync: Specifies vertical syncronisation: If set to true, the driver will wait
for the vertical retrace period, otherwise not.
\param receiver: A user created event receiver.
\param sdk_version_do_not_use: Don't use or change this parameter. Always set it to
@ -284,13 +282,13 @@ namespace irr
IEventReceiver* receiver = 0,
const c8* sdk_version_do_not_use = IRRLICHT_SDK_VERSION);
//! Creates an Irrlicht device with the option to specify advanced parameters.
//! Creates an Irrlicht device with the option to specify advanced parameters.
/** Usually you should used createDevice() for creating an Irrlicht Engine device.
Use this function only if you wish to specify advanced parameters like a window
handle in which the device should be created.
\param parameters: Structure containing advanced parameters for the creation of the device.
See irr::SIrrlichtCreationParameters for details.
\return Returns pointer to the created IrrlichtDevice or null if the
\return Returns pointer to the created IrrlichtDevice or null if the
device could not be created. */
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(
const SIrrlichtCreationParameters& parameters);

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
#include "C3DSMeshFileLoader.h"
#include "os.h"
#include "SMeshBuffer.h"
@ -1262,3 +1265,4 @@ void C3DSMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_3DS_LOADER_

File diff suppressed because it is too large Load Diff

View File

@ -1,504 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
//B3D file loader by Luke Hoschke, File format by Mark Sibly
#ifndef __C_ANIMATED_MESH_B3D_H_INCLUDED__
#define __C_ANIMATED_MESH_B3D_H_INCLUDED__
#include "IAnimatedMeshB3d.h"
#include "IMesh.h"
#include "IReadFile.h"
#include "SMeshBuffer.h"
#include "S3DVertex.h"
#include "irrString.h"
#include "matrix4.h"
#include "quaternion.h"
namespace irr
{
namespace video
{
class IVideoDriver;
} // end namespace video
namespace scene
{
class CAnimatedMeshB3d : public IAnimatedMeshB3d, public IMesh
{
public:
//! constructor
CAnimatedMeshB3d(video::IVideoDriver* driver);
//! destructor
virtual ~CAnimatedMeshB3d();
//! loads an B3d file
virtual bool loadFile(io::IReadFile* file);
//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
virtual s32 getFrameCount();
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1);
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const;
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const;
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const;
//! returns an axis aligned bounding box
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! set user axis aligned bounding box
virtual void setBoundingBox( const core::aabbox3df& box);
//! sets a flag of all contained materials to a new value
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue);
//! Returns the type of the animated mesh.
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
//! Returns a pointer to a transformation matrix of a part of the
//! mesh based on a frame time.
virtual core::matrix4* getMatrixOfJoint(s32 jointNumber, s32 frame);
//! Gets joint count.
virtual s32 getJointCount() const;
//! Gets the name of a joint.
virtual const c8* getJointName(s32 number) const;
//! Gets a joint number from its name
virtual s32 getJointNumber(const c8* name) const;
virtual core::matrix4* getLocalMatrixOfJoint(s32 jointNumber);
virtual core::matrix4* getMatrixOfJointUnanimated(s32 jointNumber);
virtual void setJointAnimation(s32 jointNumber, bool On);
//!Update Normals when Animating
//!False= Don't (default)
//!True= Update normals, slower
virtual void updateNormalsWhenAnimating(bool on);
//!Sets Interpolation Mode
//!0- Constant
//!1- Linear (default)
virtual void setInterpolationMode(s32 mode);
//!Want should happen on when animating
//!0-Nothing
//!1-Update nodes only
//!2-Update skin only
//!3-Update both nodes and skin (default)
virtual void setAnimateMode(s32 mode);
//!Convert all mesh buffers to use tangent vertices
virtual void convertToTangents();
//New Animation System Stuff (WIP)...
virtual void recoverJointsFromMesh(core::array<ISceneNode*> &JointChildSceneNodes);
virtual void tranferJointsToMesh(core::array<ISceneNode*> &JointChildSceneNodes);
virtual void createJoints(core::array<ISceneNode*> &JointChildSceneNodes, ISceneNode* AnimatedMeshSceneNode, ISceneManager* SceneManager);
private:
struct SB3DMeshBuffer : public IMeshBuffer
{
SB3DMeshBuffer()
{
#ifdef _DEBUG
setDebugName("SSkinMeshBuffer");
#endif
}
~SB3DMeshBuffer() {};
virtual const video::SMaterial& getMaterial() const
{
return Material;
}
virtual video::SMaterial& getMaterial()
{
return Material;
}
virtual video::S3DVertex *getVertex(u32 index)
{
if (VertexType==video::EVT_STANDARD) return &Vertices_Standard[index];
if (VertexType==video::EVT_TANGENTS) return (video::S3DVertex*)&Vertices_Tangents[index];
return (video::S3DVertex*)&Vertices_2TCoords[index];
}
virtual const void* getVertices() const
{
if (VertexType==video::EVT_STANDARD) return Vertices_Standard.const_pointer();
if (VertexType==video::EVT_TANGENTS) return Vertices_Tangents.const_pointer();
return Vertices_2TCoords.const_pointer();
}
virtual void* getVertices()
{
if (VertexType==video::EVT_STANDARD) return Vertices_Standard.pointer();
if (VertexType==video::EVT_TANGENTS) return Vertices_Tangents.pointer();
return Vertices_2TCoords.pointer();
}
virtual u32 getVertexCount() const
{
if (VertexType==video::EVT_STANDARD) return Vertices_Standard.size();
if (VertexType==video::EVT_TANGENTS) return Vertices_Tangents.size();
return Vertices_2TCoords.size();
}
virtual const u16* getIndices() const
{
return Indices.const_pointer();
}
virtual u16* getIndices()
{
return Indices.pointer();
}
virtual u32 getIndexCount() const
{
return Indices.size();
}
virtual const core::aabbox3d<f32>& getBoundingBox() const
{
return BoundingBox;
}
virtual void setBoundingBox( const core::aabbox3df& box)
{
BoundingBox = box;
}
virtual void recalculateBoundingBox()
{
if (VertexType==video::EVT_STANDARD)
{
if (Vertices_Standard.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_Standard[0].Pos);
for (u32 i=1; i<Vertices_Standard.size(); ++i)
BoundingBox.addInternalPoint(Vertices_Standard[i].Pos);
}
}
else if (VertexType==video::EVT_2TCOORDS)
{
if (Vertices_2TCoords.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_2TCoords[0].Pos);
for (u32 i=1; i<Vertices_2TCoords.size(); ++i)
BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos);
}
}
else
{
if (Vertices_Tangents.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_Tangents[0].Pos);
for (u32 i=1; i<Vertices_Tangents.size(); ++i)
BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos);
}
}
}
virtual video::E_VERTEX_TYPE getVertexType() const
{
return VertexType;
}
//! returns the byte size (stride, pitch) of the vertex
virtual u32 getVertexPitch() const
{
if (VertexType==video::EVT_STANDARD) return sizeof ( video::S3DVertex );
if (VertexType==video::EVT_TANGENTS) return sizeof ( video::S3DVertexTangents );
return sizeof ( video::S3DVertex2TCoords );
}
virtual void MoveTo_2TCoords()
{
if (VertexType==video::EVT_STANDARD)
{
for(u32 n=0;n<Vertices_Standard.size();++n)
{
video::S3DVertex2TCoords Vertex;
Vertex.Color=Vertices_Standard[n].Color;
Vertex.Pos=Vertices_Standard[n].Pos;
Vertex.Normal=Vertices_Standard[n].Normal;
Vertex.TCoords=Vertices_Standard[n].TCoords;
Vertices_2TCoords.push_back(Vertex);
}
Vertices_Standard.clear();
VertexType=video::EVT_2TCOORDS;
}
}
virtual void MoveTo_Tangents()
{
if (VertexType==video::EVT_STANDARD)
{
for(u32 n=0;n<Vertices_Standard.size();++n)
{
video::S3DVertexTangents Vertex;
Vertex.Color=Vertices_Standard[n].Color;
Vertex.Pos=Vertices_Standard[n].Pos;
Vertex.Normal=Vertices_Standard[n].Normal;
Vertex.TCoords=Vertices_Standard[n].TCoords;
Vertices_Tangents.push_back(Vertex);
}
Vertices_Standard.clear();
VertexType=video::EVT_TANGENTS;
}
else if (VertexType==video::EVT_2TCOORDS)
{
for(u32 n=0;n<Vertices_2TCoords.size();++n)
{
video::S3DVertexTangents Vertex;
Vertex.Color=Vertices_2TCoords[n].Color;
Vertex.Pos=Vertices_2TCoords[n].Pos;
Vertex.Normal=Vertices_2TCoords[n].Normal;
Vertex.TCoords=Vertices_2TCoords[n].TCoords;
//Vertex.TCoords2=Vertices_2TCoords[n].TCoords2;
Vertices_Tangents.push_back(Vertex);
}
Vertices_2TCoords.clear();
VertexType=video::EVT_TANGENTS;
}
}
//! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
{}
//! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other)
{}
video::SMaterial Material;
video::E_VERTEX_TYPE VertexType;
core::array<video::S3DVertexTangents> Vertices_Tangents;
core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
core::array<video::S3DVertex> Vertices_Standard;
core::array<u16> Indices;
core::aabbox3d<f32> BoundingBox;
};
struct B3dChunk
{
c8 name[4];
s32 length;
s32 startposition;
};
s32 AnimFlags;
s32 AnimFrames; //how many frames in anim
f32 AnimFPS;
struct SB3dBone
{
s32 vertex_id;
f32 weight;
core::vector3df pos;
core::vector3df normal;
video::S3DVertex *vertex;
};
struct SB3dPositionKey
{
s32 frame;
core::vector3df position;
};
struct SB3dScaleKey
{
s32 frame;
core::vector3df scale;
};
struct SB3dRotationKey
{
s32 frame;
core::quaternion rotation;
};
struct SB3dNode
{
core::stringc Name;
core::vector3df position;
core::vector3df scale;
core::quaternion rotation;
core::vector3df Animatedposition;
core::vector3df Animatedscale;
core::quaternion Animatedrotation;
core::matrix4 GlobalAnimatedMatrix;
core::matrix4 LocalAnimatedMatrix;
core::matrix4 LocalMatrix;
core::matrix4 GlobalMatrix;
core::matrix4 GlobalInversedMatrix;
bool Animate; //Move this nodes local matrix when animating?
bool AnimatingPositionKeys;
bool AnimatingScaleKeys;
bool AnimatingRotationKeys;
bool HasScaleAnimation;
core::array<SB3dPositionKey> PositionKeys;
core::array<SB3dScaleKey> ScaleKeys;
core::array<SB3dRotationKey> RotationKeys;
core::array<SB3dBone> Bones;
core::array<SB3dNode*> Nodes;
};
core::array<SB3dNode*> Nodes;
core::array<SB3dNode*> RootNodes;
struct SB3dTexture
{
irr::video::ITexture* Texture;
s32 Flags;
s32 Blend;
f32 Xpos;
f32 Ypos;
f32 Xscale;
f32 Yscale;
f32 Angle;
};
struct SB3dMaterial
{
irr::video::SMaterial* Material;
f32 red, green, blue, alpha;
f32 shininess;
s32 blend,fx;
SB3dTexture *Textures[2];
};
bool ReadChunkTEXS(io::IReadFile* file);
bool ReadChunkBRUS(io::IReadFile* file);
bool ReadChunkMESH(io::IReadFile* file, SB3dNode *InNode);
bool ReadChunkVRTS(io::IReadFile* file, SB3dNode *InNode, SB3DMeshBuffer *MeshBuffer, s32 Vertices_Start);
bool ReadChunkTRIS(io::IReadFile* file, SB3dNode *InNode, SB3DMeshBuffer *MeshBuffer, s32 Vertices_Start);
bool ReadChunkNODE(io::IReadFile* file, SB3dNode *InNode);
bool ReadChunkBONE(io::IReadFile* file, SB3dNode *InNode);
bool ReadChunkKEYS(io::IReadFile* file, SB3dNode *InNode);
bool ReadChunkANIM(io::IReadFile* file, SB3dNode *InNode);
void normalizeWeights();
void animate(s32 frame,s32 startFrameLoop, s32 endFrameLoop);
void CalculateGlobalMatrixes(SB3dNode *Node,SB3dNode *ParentNode);
void animateSkin(f32 frame,f32 startFrame, f32 endFrame,SB3dNode *InNode,SB3dNode *ParentNode);
void getNodeAnimation(f32 frame,SB3dNode *Node,core::vector3df &position, core::vector3df &scale, core::quaternion &rotation);
void animateNodes(f32 frame,f32 startFrame, f32 endFrame);
void slerp(core::quaternion A,core::quaternion B,core::quaternion &C,f32 t);
void calculateTangents(core::vector3df& normal,
core::vector3df& tangent, core::vector3df& binormal,
core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3,
core::vector2df& tc1, core::vector2df& tc2, core::vector2df& tc3);
void createSkelton_Helper(ISceneManager* SceneManager, core::array<ISceneNode*> &JointChildSceneNodes, ISceneNode *AnimatedMeshSceneNode, ISceneNode* ParentNode, SB3dNode *ParentB3dNode, SB3dNode *B3dNode);
core::array<B3dChunk> B3dStack;
f32 totalTime;
bool HasAnimation;
bool HasBones;
s32 lastCalculatedFrame;
s32 lastAnimateMode;
bool NormalsInFile;
bool AnimateNormals;
//0- Constant 1- Linear
s32 InterpolationMode;
//0-None 1-Update nodes only 2-Update skin only 3-Update both nodes and skin
s32 AnimateMode;
core::stringc readString(io::IReadFile* file);
core::stringc stripPathString(core::stringc oldstring, bool keepPath);
void readFloats(io::IReadFile* file, f32* vec, u32 count);
core::aabbox3d<f32> BoundingBox;
core::array<SB3dMaterial> Materials;
core::array<SB3dTexture> Textures;
core::array<video::S3DVertex2TCoords*> BaseVertices;
core::array<bool> Vertices_Moved;
core::array<f32> Vertices_Alpha;
core::array<s32> AnimatedVertices_VertexID;
core::array<SB3DMeshBuffer*> AnimatedVertices_MeshBuffer;
core::array<SB3DMeshBuffer*> Buffers;
video::IVideoDriver* Driver;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
#include "CAnimatedMeshMD2.h"
#include "os.h"
#include "SColor.h"
@ -758,3 +761,4 @@ const c8* CAnimatedMeshMD2::getAnimationName(s32 nr) const
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_MD2_LOADER_

View File

@ -18,7 +18,7 @@ namespace irr
namespace scene
{
class CAnimatedMeshMD2 : public IAnimatedMeshMD2, public IMesh
class CAnimatedMeshMD2 : public IAnimatedMeshMD2
{
public:
@ -45,7 +45,7 @@ namespace scene
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const;
@ -62,18 +62,18 @@ namespace scene
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
//! Returns frame loop data for a special MD2 animation type.
virtual void getFrameLoop(EMD2_ANIMATION_TYPE,
virtual void getFrameLoop(EMD2_ANIMATION_TYPE,
s32& outBegin, s32& outEnd, s32& outFps) const;
//! Returns frame loop data for a special MD2 animation type.
virtual bool getFrameLoop(const c8* name,
virtual bool getFrameLoop(const c8* name,
s32& outBegin, s32& outEnd, s32& outFps) const;
//! Returns amount of md2 animations in this file.
virtual s32 getAnimationCount() const;
//! Returns name of md2 animation.
//! \param nr: Zero based index of animation.
//! Returns name of md2 animation.
//! \param nr: Zero based index of animation.
virtual const c8* getAnimationName(s32 nr) const;
private:

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
#include "CAnimatedMeshMD3.h"
#include "os.h"
@ -411,3 +414,4 @@ E_ANIMATED_MESH_TYPE CAnimatedMeshMD3::getMeshType() const
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_MD3_LOADER_

View File

@ -43,6 +43,43 @@ namespace scene
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
//link?
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const
{
return 0;
}
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const
{
return 0;
}
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const
{
return 0;
}
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{
return;
}
//! set user axis aligned bounding box
virtual void setBoundingBox( const core::aabbox3df& box)
{
return;
}
private:
//! animates one frame
inline void Animate (u32 frame);
@ -62,7 +99,7 @@ namespace scene
SCacheInfo ( s32 frame = -1, s32 start = -1, s32 end = -1 )
: Frame ( frame ), startFrameLoop ( start ),
endFrameLoop ( end ) {}
bool operator == ( const SCacheInfo &other ) const
{
return 0 == memcmp ( this, &other, sizeof ( SCacheInfo ) );

View File

@ -1,751 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CAnimatedMeshMS3D.h"
#include "os.h"
#include "IVideoDriver.h"
#include "quaternion.h"
namespace irr
{
namespace scene
{
// byte-align structures
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
// File header
struct MS3DHeader
{
c8 ID[10];
s32 Version;
} PACK_STRUCT;
// Vertex information
struct MS3DVertex
{
u8 Flags;
f32 Vertex[3];
s8 BoneID;
u8 RefCount;
} PACK_STRUCT;
// Triangle information
struct MS3DTriangle
{
u16 Flags;
u16 VertexIndices[3];
f32 VertexNormals[3][3];
f32 S[3], T[3];
u8 SmoothingGroup;
u8 GroupIndex;
} PACK_STRUCT;
// Material information
struct MS3DMaterial
{
s8 Name[32];
f32 Ambient[4];
f32 Diffuse[4];
f32 Specular[4];
f32 Emissive[4];
f32 Shininess; // 0.0f - 128.0f
f32 Transparency; // 0.0f - 1.0f
u8 Mode; // 0, 1, 2 is unused now
s8 Texture[128];
s8 Alphamap[128];
} PACK_STRUCT;
// Joint information
struct MS3DJoint
{
u8 Flags;
s8 Name[32];
s8 ParentName[32];
f32 Rotation[3];
f32 Translation[3];
u16 NumRotationKeyframes;
u16 NumTranslationKeyframes;
} PACK_STRUCT;
// Keyframe data
struct MS3DKeyframe
{
f32 Time;
f32 Parameter[3];
} PACK_STRUCT;
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
//! constructor
CAnimatedMeshMS3D::CAnimatedMeshMS3D(video::IVideoDriver* driver)
: Driver(driver)
{
if (Driver)
Driver->grab();
lastCalculatedFrame = -1;
}
//! destructor
CAnimatedMeshMS3D::~CAnimatedMeshMS3D()
{
if (Driver)
Driver->drop();
}
//! loads an ms3d file
bool CAnimatedMeshMS3D::loadFile(io::IReadFile* file)
{
u32 i=0;
if (!file)
return false;
HasAnimation = false;
// find file size
size_t fileSize = file->getSize();
// read whole file
u8* buffer = new u8[fileSize];
size_t read = (s32)file->read(buffer, fileSize);
if (read != fileSize)
{
delete [] buffer;
os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR);
return false;
}
// read header
const u8 *pPtr = (u8*)((void*)buffer);
MS3DHeader *pHeader = (MS3DHeader*)pPtr;
pPtr += sizeof(MS3DHeader);
if ( strncmp( pHeader->ID, "MS3D000000", 10 ) != 0 )
{
delete [] buffer;
os::Printer::log("Not a valid Milkshape3D Model File. Loading failed", file->getFileName(), ELL_ERROR);
return false;
}
#ifdef __BIG_ENDIAN__
pHeader->Version = os::Byteswap::byteswap(pHeader->Version);
#endif
if ( pHeader->Version < 3 || pHeader->Version > 4 )
{
delete [] buffer;
os::Printer::log("Only Milkshape3D version 1.3 and 1.4 is supported. Loading failed", file->getFileName(), ELL_ERROR);
return false;
}
// get pointers to data
// vertices
u16 numVertices = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numVertices = os::Byteswap::byteswap(numVertices);
#endif
pPtr += sizeof(u16);
MS3DVertex *vertices = (MS3DVertex*)pPtr;
pPtr += sizeof(MS3DVertex) * numVertices;
#ifdef __BIG_ENDIAN__
for (i=0; i<numVertices; ++i)
for (u32 j=0; j<3; ++j)
vertices[i].Vertex[j] = os::Byteswap::byteswap(vertices[i].Vertex[j]);
#endif
// triangles
u16 numTriangles = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numTriangles = os::Byteswap::byteswap(numTriangles);
#endif
pPtr += sizeof(u16);
MS3DTriangle *triangles = (MS3DTriangle*)pPtr;
pPtr += sizeof(MS3DTriangle) * numTriangles;
#ifdef __BIG_ENDIAN__
for (i=0; i<numTriangles; ++i)
{
triangles[i].Flags = os::Byteswap::byteswap(triangles[i].Flags);
for (u32 j=0; j<3; ++j)
{
triangles[i].VertexIndices[j] = os::Byteswap::byteswap(triangles[i].VertexIndices[j]);
for (u16 k=0; k<3; ++k)
triangles[i].VertexNormals[j][k] = os::Byteswap::byteswap(triangles[i].VertexNormals[j][k]);
triangles[i].S[j] = os::Byteswap::byteswap(triangles[i].S[j]);
triangles[i].T[j] = os::Byteswap::byteswap(triangles[i].T[j]);
}
}
#endif
// groups
u16 numGroups = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numGroups = os::Byteswap::byteswap(numGroups);
#endif
pPtr += sizeof(u16);
//skip groups
for (i=0; i<numGroups; ++i)
{
Groups.push_back(SGroup());
SGroup& grp = Groups.getLast();
// The byte flag is before the name, so add 1
grp.Name = ((const c8*) pPtr) + 1;
pPtr += 33; // name and 1 byte flags
u16 triangleCount = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
triangleCount = os::Byteswap::byteswap(triangleCount);
#endif
pPtr += sizeof(u16);
//pPtr += sizeof(u16) * triangleCount; // triangle indices
for (u32 j=0; j<triangleCount; ++j)
{
#ifdef __BIG_ENDIAN__
grp.VertexIds.push_back(os::Byteswap::byteswap(*(u16*)pPtr));
#else
grp.VertexIds.push_back(*(u16*)pPtr);
#endif
pPtr += sizeof (u16);
}
grp.MaterialIdx = *(u8*)pPtr;
pPtr += sizeof(c8); // material index
}
// skip materials
u16 numMaterials = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numMaterials = os::Byteswap::byteswap(numMaterials);
#endif
pPtr += sizeof(u16);
// MS3DMaterial *materials = (MS3DMaterial*)pPtr;
// pPtr += sizeof(MS3DMaterial) * numMaterials;
// if there are no materials, add at least one buffer
if(numMaterials == 0)
Buffers.push_back(SSharedMeshBuffer(&AnimatedVertices));
for (i=0; i<numMaterials; ++i)
{
MS3DMaterial *material = (MS3DMaterial*)pPtr;
#ifdef __BIG_ENDIAN__
for (u32 j=0; j<4; ++j)
material->Ambient[j] = os::Byteswap::byteswap(material->Ambient[j]);
for (u32 j=0; j<4; ++j)
material->Diffuse[j] = os::Byteswap::byteswap(material->Diffuse[j]);
for (u32 j=0; j<4; ++j)
material->Specular[j] = os::Byteswap::byteswap(material->Specular[j]);
for (u32 j=0; j<4; ++j)
material->Emissive[j] = os::Byteswap::byteswap(material->Emissive[j]);
material->Shininess = os::Byteswap::byteswap(material->Shininess);
material->Transparency = os::Byteswap::byteswap(material->Transparency);
#endif
pPtr += sizeof(MS3DMaterial);
Buffers.push_back(SSharedMeshBuffer(&AnimatedVertices));
SSharedMeshBuffer& tmpBuffer = Buffers.getLast();
tmpBuffer.Material.MaterialType = video::EMT_SOLID;
tmpBuffer.Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor ();
tmpBuffer.Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor ();
tmpBuffer.Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor ();
tmpBuffer.Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor ();
tmpBuffer.Material.Shininess = material->Shininess;
tmpBuffer.Material.Textures[0] = Driver->getTexture((const c8*)material->Texture);
if (tmpBuffer.Material.Textures[0]==0)
tmpBuffer.Material.Textures[0] = Driver->getTexture(strrchr((const c8*)material->Texture, '/')+1);
}
// animation time
f32 framesPerSecond = *(f32*)pPtr;
#ifdef __BIG_ENDIAN__
framesPerSecond = os::Byteswap::byteswap(framesPerSecond);
#endif
pPtr += sizeof(f32) * 2; // fps and current time
s32 frameCount = *(s32*)pPtr;
#ifdef __BIG_ENDIAN__
frameCount = os::Byteswap::byteswap(frameCount);
#endif
pPtr += sizeof(s32);
totalTime = (frameCount / framesPerSecond) * 1000.0f;
u16 jointCount = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
jointCount = os::Byteswap::byteswap(jointCount);
#endif
pPtr += sizeof(u16);
// load joints
SJoint t;
for (i=0; i<jointCount; ++i)
{
MS3DJoint *pJoint = (MS3DJoint*)pPtr;
#ifdef __BIG_ENDIAN__
for (u32 j=0; j<3; ++j)
pJoint->Rotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]);
for (u32 j=0; j<3; ++j)
pJoint->Translation[j] = os::Byteswap::byteswap(pJoint->Translation[j]);
pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes);
pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes);
#endif
pPtr += sizeof(MS3DJoint);
Joints.push_back(t);
SJoint& jnt = Joints[Joints.size()-1];
jnt.Name = pJoint->Name;
jnt.Index = i;
jnt.Rotation.X = pJoint->Rotation[0];
jnt.Rotation.Y = pJoint->Rotation[1];
jnt.Rotation.Z = pJoint->Rotation[2];
jnt.Translation.X = pJoint->Translation[0];
jnt.Translation.Y = pJoint->Translation[1];
jnt.Translation.Z = pJoint->Translation[2];
jnt.ParentName = pJoint->ParentName;
jnt.Parent = -1;
if (pJoint->NumRotationKeyframes ||
pJoint->NumTranslationKeyframes)
HasAnimation = true;
// get rotation keyframes
for (u32 j=0; j<pJoint->NumRotationKeyframes; ++j)
{
MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
#ifdef __BIG_ENDIAN__
kf->Time = os::Byteswap::byteswap(kf->Time);
for (u32 l=0; l<3; ++l)
kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
#endif
pPtr += sizeof(MS3DKeyframe);
SKeyframe k;
k.timeindex = kf->Time * 1000.0f;
k.data.X = kf->Parameter[0];
k.data.Y = kf->Parameter[1];
k.data.Z = kf->Parameter[2];
jnt.RotationKeys.push_back(k);
}
// get translation keyframes
for (u32 j=0; j<pJoint->NumTranslationKeyframes; ++j)
{
MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
#ifdef __BIG_ENDIAN__
kf->Time = os::Byteswap::byteswap(kf->Time);
for (u32 l=0; l<3; ++l)
kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
#endif
pPtr += sizeof(MS3DKeyframe);
SKeyframe k;
k.timeindex = kf->Time * 1000.0f;
k.data.X = kf->Parameter[0];
k.data.Y = kf->Parameter[1];
k.data.Z = kf->Parameter[2];
jnt.TranslationKeys.push_back(k);
}
}
//find parent of every joint
for (i=0; i<Joints.size(); ++i)
{
if (Joints[i].ParentName.size() != 0)
{
for (u32 j=0; j<Joints.size(); ++j)
if (i != j && Joints[i].ParentName == Joints[j].Name)
{
Joints[i].Parent = j;
break;
}
if (Joints[i].Parent == -1)
os::Printer::log("Found joint in model without parent.", ELL_WARNING);
}
}
// sets up all joints with initial rotation and translation
for (i=0; i<Joints.size(); ++i)
{
SJoint& jnt = Joints[i];
jnt.RelativeTransformation.setRotationRadians(jnt.Rotation);
jnt.RelativeTransformation.setTranslation(jnt.Translation);
if (jnt.Parent == -1)
jnt.AbsoluteTransformation = jnt.RelativeTransformation;
else
{
jnt.AbsoluteTransformation = Joints[jnt.Parent].AbsoluteTransformation;
jnt.AbsoluteTransformation *= jnt.RelativeTransformation;
}
jnt.AbsoluteTransformationAnimated = jnt.AbsoluteTransformation;
}
// create vertices and indices, attach them to the joints.
video::S3DVertex v;
for (i=0; i<numTriangles; ++i)
{
for (u32 j = 0; j<3; ++j)
{
v.TCoords.X = triangles[i].S[j];
v.TCoords.Y = triangles[i].T[j];
v.Normal.X = triangles[i].VertexNormals[j][0];
v.Normal.Y = triangles[i].VertexNormals[j][1];
v.Normal.Z = triangles[i].VertexNormals[j][2];
if(triangles[i].GroupIndex < Groups.size() && Groups[triangles[i].GroupIndex].MaterialIdx < Buffers.size())
v.Color = Buffers[Groups[triangles[i].GroupIndex].MaterialIdx].Material.DiffuseColor;
else
v.Color.set(255,255,255,255);
v.Pos.X = vertices[triangles[i].VertexIndices[j]].Vertex[0];
v.Pos.Y = vertices[triangles[i].VertexIndices[j]].Vertex[1];
v.Pos.Z = vertices[triangles[i].VertexIndices[j]].Vertex[2];
//look, if we already have this vertex in our vertex array
s32 index = -1;
for (u32 iV = 0; iV < Vertices.size(); ++iV)
{
if (v == Vertices[iV])
{
index = (s32)iV;
break;
}
}
if (index == -1)
{
s32 boneid = vertices[triangles[i].VertexIndices[j]].BoneID;
if (boneid>=0 && boneid<(s32)Joints.size())
Joints[boneid].VertexIds.push_back(Vertices.size());
Vertices.push_back(v);
index = Vertices.size() - 1;
}
Indices.push_back(index);
}
}
//create groups
s32 iIndex = -1;
for (i=0; i<Groups.size(); ++i)
{
SGroup& grp = Groups[i];
if (grp.MaterialIdx >= Buffers.size())
grp.MaterialIdx = 0;
core::array<u16>& indices = Buffers[grp.MaterialIdx].Indices;
for (u32 k=0; k<grp.VertexIds.size(); ++k)
for (u32 l=0; l<3; ++l)
indices.push_back(Indices[++iIndex]);
}
// calculate bounding box
if (!Vertices.empty())
BoundingBox.reset(Vertices[0].Pos);
for (i=0; i<Vertices.size(); ++i)
BoundingBox.addInternalPoint(Vertices[i].Pos);
for (i=0; i<Buffers.size(); ++i)
Buffers[i].recalculateBoundingBox();
// inverse translate and rotate all vertices for making animation easier
if (HasAnimation)
{
for (u32 k=0; k<Joints.size(); ++k)
{
for (u32 l=0; l<Joints[k].VertexIds.size(); ++l)
{
Joints[k].AbsoluteTransformation.inverseTranslateVect(
Vertices[Joints[k].VertexIds[l]].Pos);
Joints[k].AbsoluteTransformation.inverseRotateVect(
Vertices[Joints[k].VertexIds[l]].Pos);
Joints[k].AbsoluteTransformation.inverseRotateVect(
Vertices[Joints[k].VertexIds[l]].Normal);
}
}
}
AnimatedVertices = Vertices;
delete [] buffer;
return true;
}
//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
s32 CAnimatedMeshMS3D::getFrameCount()
{
return (s32)totalTime;
}
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
IMesh* CAnimatedMeshMS3D::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
{
animate(frame);
return this;
}
void CAnimatedMeshMS3D::getKeyframeData(const core::array<SKeyframe>& keys, f32 time, core::vector3df& outdata) const
{
if (keys.size())
{
if (time < keys[0].timeindex)
{
outdata = keys[0].data;
return;
}
if (time > keys.getLast().timeindex)
{
outdata = keys.getLast().data;
return;
}
for (u32 i=0; i<keys.size()-1; ++i)
{
if (keys[i].timeindex <= time && keys[i+1].timeindex >= time)
{
f32 interpolate = (time - keys[i].timeindex)/(keys[i+1].timeindex - keys[i].timeindex);
outdata = keys[i].data + ((keys[i+1].data - keys[i].data) * interpolate);
return;
}
}
}
}
void CAnimatedMeshMS3D::getKeyframeRotation(const core::array<SKeyframe>& keys, f32 time, core::vector3df& outdata) const
{
if (keys.size())
{
if (time < keys[0].timeindex)
{
outdata = keys[0].data;
return;
}
if (time > keys.getLast().timeindex)
{
outdata = keys.getLast().data;
return;
}
for (u32 i=0; i<keys.size()-1; ++i)
{
if (keys[i].timeindex <= time && keys[i+1].timeindex >= time)
{
// core::quaternion q1(keys[i].data);
// core::quaternion q2(keys[i+1].data);
f32 interpolate = (time - keys[i].timeindex)/(keys[i+1].timeindex - keys[i].timeindex);
core::quaternion q;
q.slerp(keys[i].data, keys[i+1].data, interpolate);
q.toEuler(outdata);
return;
}
}
}
}
//! Returns a pointer to a transformation matrix of a part of the
//! mesh based on a frame time.
core::matrix4* CAnimatedMeshMS3D::getMatrixOfJoint(s32 jointNumber, s32 frame)
{
if (jointNumber < 0 || jointNumber >= (s32)Joints.size())
return 0;
animate(frame);
return &Joints[jointNumber].AbsoluteTransformationAnimated;
}
//! Gets joint count.
s32 CAnimatedMeshMS3D::getJointCount() const
{
return Joints.size();
}
//! Gets the name of a joint.
const c8* CAnimatedMeshMS3D::getJointName(s32 number) const
{
if (number < 0 || number >= (s32)Joints.size())
return 0;
return Joints[number].Name.c_str();
}
//! Gets a joint number from its name
s32 CAnimatedMeshMS3D::getJointNumber(const c8* name) const
{
for (s32 i=0; i<(s32)Joints.size(); ++i)
if (Joints[i].Name == name)
return i;
return -1;
}
void CAnimatedMeshMS3D::animate(s32 frame)
{
if (!HasAnimation || lastCalculatedFrame == frame)
return;
f32 time = (f32)frame;
core::matrix4 transform;
lastCalculatedFrame = frame;
u32 i;
for (i=0; i<Joints.size(); ++i)
{
core::vector3df translation = Joints[i].Translation;
core::vector3df rotation = Joints[i].Rotation;
// find keyframe translation and rotation
getKeyframeData(Joints[i].TranslationKeys, time, translation);
getKeyframeRotation(Joints[i].RotationKeys, time, rotation);
transform.makeIdentity();
transform.setRotationRadians(rotation);
transform.setTranslation(translation);
Joints[i].AbsoluteTransformationAnimated = Joints[i].RelativeTransformation * transform;
if (Joints[i].Parent != -1)
Joints[i].AbsoluteTransformationAnimated = Joints[Joints[i].Parent].AbsoluteTransformationAnimated * Joints[i].AbsoluteTransformationAnimated;
if (i==0)
BoundingBox.reset(Joints[0].AbsoluteTransformationAnimated.getTranslation());
else
BoundingBox.addInternalPoint(Joints[i].AbsoluteTransformationAnimated.getTranslation());
// transform all vertices
for (u32 j=0; j<Joints[i].VertexIds.size(); ++j)
{
Joints[i].AbsoluteTransformationAnimated.transformVect(
AnimatedVertices[Joints[i].VertexIds[j]].Pos,
Vertices[Joints[i].VertexIds[j]].Pos
);
Joints[i].AbsoluteTransformationAnimated.transformVect(
AnimatedVertices[Joints[i].VertexIds[j]].Normal,
Vertices[Joints[i].VertexIds[j]].Normal
);
// TODO: this could be done much more faster by
// first getting 8 extreme points and putting them in.
BoundingBox.addInternalPoint(AnimatedVertices[Joints[i].VertexIds[j]].Pos);
}
}
for (i=0; i<Buffers.size(); ++i)
Buffers[i].recalculateBoundingBox();
}
//! returns amount of mesh buffers.
u32 CAnimatedMeshMS3D::getMeshBufferCount() const
{
return Buffers.size();
}
//! returns pointer to a mesh buffer
IMeshBuffer* CAnimatedMeshMS3D::getMeshBuffer(u32 nr) const
{
if (nr < Buffers.size())
return (IMeshBuffer*) &Buffers[nr];
else
return 0;
}
//! Returns pointer to a mesh buffer which fits a material
IMeshBuffer* CAnimatedMeshMS3D::getMeshBuffer( const video::SMaterial &material) const
{
for (u32 i=0; i<Buffers.size(); ++i)
{
if (Buffers[i].getMaterial() == material)
return (IMeshBuffer*) &Buffers[i];
}
return 0;
}
//! returns an axis aligned bounding box
const core::aabbox3d<f32>& CAnimatedMeshMS3D::getBoundingBox() const
{
return BoundingBox;
}
//! set user axis aligned bounding box
void CAnimatedMeshMS3D::setBoundingBox( const core::aabbox3df& box)
{
BoundingBox = box;
}
//! sets a flag of all contained materials to a new value
void CAnimatedMeshMS3D::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{
for (u32 i=0; i<Buffers.size(); ++i)
Buffers[i].Material.setFlag(flag, newvalue);
}
//! Returns the type of the animated mesh.
E_ANIMATED_MESH_TYPE CAnimatedMeshMS3D::getMeshType() const
{
return EAMT_MS3D;
}
//! returns the byte size (stride, pitch) of the vertex
} // end namespace scene
} // end namespace irr

View File

@ -1,140 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_ANIMATED_MESH_MS3D_H_INCLUDED__
#define __C_ANIMATED_MESH_MS3D_H_INCLUDED__
#include "IAnimatedMeshMS3D.h"
#include "IMesh.h"
#include "IReadFile.h"
#include "S3DVertex.h"
#include "irrString.h"
#include "SSharedMeshBuffer.h"
namespace irr
{
namespace video
{
class IVideoDriver;
} // end namespace video
namespace scene
{
class CAnimatedMeshMS3D : public IAnimatedMeshMS3D, public IMesh
{
public:
//! constructor
CAnimatedMeshMS3D(video::IVideoDriver* driver);
//! destructor
virtual ~CAnimatedMeshMS3D();
//! loads an md2 file
virtual bool loadFile(io::IReadFile* file);
//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
virtual s32 getFrameCount();
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1);
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const;
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const;
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const;
//! returns an axis aligned bounding box
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! set user axis aligned bounding box
virtual void setBoundingBox( const core::aabbox3df& box);
//! sets a flag of all contained materials to a new value
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue);
//! Returns the type of the animated mesh.
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
//! Returns a pointer to a transformation matrix of a part of the
//! mesh based on a frame time.
virtual core::matrix4* getMatrixOfJoint(s32 jointNumber, s32 frame);
//! Gets joint count.
virtual s32 getJointCount() const;
//! Gets the name of a joint.
virtual const c8* getJointName(s32 number) const;
//! Gets a joint number from its name
virtual s32 getJointNumber(const c8* name) const;
private:
struct SKeyframe
{
f32 timeindex;
core::vector3df data; // translation or rotation
};
struct SJoint
{
core::stringc Name;
s32 Index;
core::vector3df Rotation;
core::vector3df Translation;
core::matrix4 RelativeTransformation;
core::matrix4 AbsoluteTransformation;
core::matrix4 AbsoluteTransformationAnimated;
core::array<SKeyframe> TranslationKeys;
core::array<SKeyframe> RotationKeys;
core::array<u16> VertexIds;
s32 Parent;
core::stringc ParentName;
};
struct SGroup
{
core::stringc Name;
core::array<u16> VertexIds;
u16 MaterialIdx;
};
void animate(s32 frame);
void getKeyframeData(const core::array<SKeyframe>& keys, f32 time, core::vector3df& outdata) const;
void getKeyframeRotation(const core::array<SKeyframe>& keys, f32 time, core::vector3df& outdata) const;
core::aabbox3d<f32> BoundingBox;
core::array<video::S3DVertex> Vertices;
core::array<video::S3DVertex> AnimatedVertices;
core::array<u16> Indices;
core::array<SJoint> Joints;
core::array<SGroup> Groups;
core::array<SSharedMeshBuffer> Buffers;
f32 totalTime;
bool HasAnimation;
s32 lastCalculatedFrame;
video::IVideoDriver* Driver;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -8,17 +8,17 @@
#include "S3DVertex.h"
#include "os.h"
#include "CShadowVolumeSceneNode.h"
#include "IAnimatedMeshMS3D.h"
#include "IAnimatedMeshMD3.h"
#include "IAnimatedMeshX.h"
#include "IAnimatedMeshB3d.h"
#include "ISkinnedMesh.h"
#include "IDummyTransformationSceneNode.h"
#include "IBoneSceneNode.h"
#include "IMaterialRenderer.h"
#include "IMesh.h"
#include "IMeshCache.h"
#include "IAnimatedMesh.h"
#include "quaternion.h"
namespace irr
{
namespace scene
@ -30,7 +30,9 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode*
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
BeginFrameTime(0), StartFrame(0), EndFrame(0), FramesPerSecond(25.f / 1000.f ),
CurrentFrameNr(0), Looping(true), ReadOnlyMaterials(false),
CurrentFrameNr(0.f), JointMode(0), JointsUsed(0),
TransitionTime(0), Transiting(0), TransitingBlend(0),
Looping(true), ReadOnlyMaterials(false),
LoopCallBack(0), PassCount(0), Shadow(0)
{
#ifdef _DEBUG
@ -53,9 +55,9 @@ CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()
if (Shadow)
Shadow->drop();
for (u32 i=0; i<JointChildSceneNodes.size(); ++i)
if (JointChildSceneNodes[i])
JointChildSceneNodes[i]->drop();
//for (u32 i=0; i<JointChildSceneNodes.size(); ++i)
// if (JointChildSceneNodes[i])
// JointChildSceneNodes[i]->drop();
if (LoopCallBack)
LoopCallBack->drop();
@ -63,44 +65,101 @@ CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()
//! Sets the current frame. From now on the animation is played from this frame.
void CAnimatedMeshSceneNode::setCurrentFrame(s32 frame)
void CAnimatedMeshSceneNode::setCurrentFrame(f32 frame)
{
// if you pass an out of range value, we just clamp it
CurrentFrameNr = core::s32_clamp ( frame, StartFrame, EndFrame );
CurrentFrameNr = core::clamp ( frame, (f32)StartFrame, (f32)EndFrame );
BeginFrameTime = os::Timer::getTime() - (s32)((CurrentFrameNr - StartFrame) / FramesPerSecond);
beginTransition(); //transite to this frame if enabled
}
//! Returns the current displayed frame number.
s32 CAnimatedMeshSceneNode::getFrameNr() const
f32 CAnimatedMeshSceneNode::getFrameNr() const
{
return CurrentFrameNr;
}
u32 CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
f32 CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
{
const s32 deltaFrame = core::floor32 ( f32 ( timeMs - BeginFrameTime ) * FramesPerSecond );
if (Transiting!=0)
{
TransitingBlend=f32(timeMs-BeginFrameTime) * Transiting;
if (TransitingBlend>1)
{
Transiting=0;
TransitingBlend=0;
}
}
if (StartFrame==EndFrame) return StartFrame; //Support for non animated meshes
if (FramesPerSecond==0) return StartFrame;
if (Looping)
{
const s32 len = EndFrame - StartFrame + 1;
// play animation looped
return StartFrame + ( deltaFrame % len );
if (FramesPerSecond>0) //forwards...
{
const s32 lenInTime = s32( f32(EndFrame - StartFrame) / FramesPerSecond);
return StartFrame + ( (timeMs - BeginFrameTime) % lenInTime) *FramesPerSecond;
}
else //backwards...
{
const s32 lenInTime = s32( f32(EndFrame - StartFrame) / -FramesPerSecond);
return EndFrame - ( (timeMs - BeginFrameTime) % lenInTime)*-FramesPerSecond;
}
}
else
{
// play animation non looped
s32 frame = StartFrame + deltaFrame;
if (frame > EndFrame)
f32 frame;
if (FramesPerSecond>0) //forwards...
{
frame = EndFrame;
if (LoopCallBack)
LoopCallBack->OnAnimationEnd(this);
const f32 deltaFrame = core::floor32 ( f32 ( timeMs - BeginFrameTime ) * FramesPerSecond );
frame = StartFrame + deltaFrame;
if (frame > (f32)EndFrame)
{
frame = (f32)EndFrame;
if (LoopCallBack)
LoopCallBack->OnAnimationEnd(this);
}
}
else //backwards... (untested)
{
const f32 deltaFrame = core::floor32 ( f32 ( timeMs - BeginFrameTime ) * -FramesPerSecond );
frame = EndFrame - deltaFrame;
if (frame < (f32)StartFrame)
{
frame = (f32)StartFrame;
if (LoopCallBack)
LoopCallBack->OnAnimationEnd(this);
}
}
return frame;
}
}
@ -157,14 +216,23 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
//! OnAnimate() is called just before rendering the whole scene.
void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
{
CurrentFrameNr = buildFrameNr ( timeMs );
if ( Mesh )
{
Box = Mesh->getBoundingBox(); //can we remove this, the box is set on 'setMesh', and without it the user can set their own boundingbox (if the normal one is too small) without it being overwritten
/*
scene::IMesh *m = Mesh->getMesh(CurrentFrameNr, 255, StartFrame, EndFrame);
if ( m )
{
Box = m->getBoundingBox();
}
*/
}
IAnimatedMeshSceneNode::OnAnimate ( timeMs );
}
@ -189,13 +257,46 @@ void CAnimatedMeshSceneNode::render()
if (!Mesh || !driver)
return;
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
s32 frame = getFrameNr();
scene::IMesh* m = Mesh->getMesh(frame, 255, StartFrame, EndFrame);
f32 frame = getFrameNr();
scene::IMesh* m;
if (Mesh->getMeshType() != EAMT_SKINNED)
m = Mesh->getMesh((s32)frame, 255, StartFrame, EndFrame);
else
{
ISkinnedMesh* skinnedMesh=(ISkinnedMesh*)Mesh;
if (JointMode &2)//write to mesh
skinnedMesh->tranferJointsToMesh(JointChildSceneNodes);
else
skinnedMesh->animateMesh(frame, 1.0f);
skinnedMesh->skinMesh();
if (JointMode &1)//read from mesh
{
skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes);
//---slow---
for (u32 n=0;n<JointChildSceneNodes.size();++n)
if (JointChildSceneNodes[n]->getParent()==this)
{
JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option
}
}
m=skinnedMesh;
}
if ( 0 == m )
{
@ -209,21 +310,6 @@ void CAnimatedMeshSceneNode::render()
u32 i,g;
// update all dummy transformation nodes
if (!JointChildSceneNodes.empty() && Mesh &&
(Mesh->getMeshType() == EAMT_MS3D || Mesh->getMeshType() == EAMT_X || Mesh->getMeshType() == EAMT_B3D ))
{
IAnimatedMeshMS3D* amm = (IAnimatedMeshMS3D*)Mesh;
core::matrix4* m;
for ( i=0; i< JointChildSceneNodes.size(); ++i)
if (JointChildSceneNodes[i])
{
m = amm->getMatrixOfJoint(i, frame);
if (m)
JointChildSceneNodes[i]->getRelativeTransformationMatrix() = *m;
}
}
if (Shadow && PassCount==1)
Shadow->setMeshToRenderFrom(m);
@ -290,14 +376,21 @@ void CAnimatedMeshSceneNode::render()
// show skeleton
if ( DebugDataVisible & scene::EDS_SKELETON )
{
if (Mesh->getMeshType() == EAMT_X)
if (Mesh->getMeshType() == EAMT_SKINNED)
{
// draw skeleton
const core::array<core::vector3df>* ds =
((IAnimatedMeshX*)Mesh)->getDrawableSkeleton(frame);
for ( g=0; g < ds->size(); g +=2 )
driver->draw3DLine((*ds)[g], (*ds)[g+1], video::SColor(0,51,66,255));
// draw skeleton
for ( g=0; g < ((ISkinnedMesh*)Mesh)->getAllJoints().size(); g +=1 )
{
ISkinnedMesh::SJoint *joint=((ISkinnedMesh*)Mesh)->getAllJoints()[g];
for (u32 n=0;n<joint->Children.size();++n)
{
driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(), joint->Children[n]->GlobalAnimatedMatrix.getTranslation(), video::SColor(0,51,66,255));
}
}
}
// show tag for quake3 models
@ -321,7 +414,7 @@ void CAnimatedMeshSceneNode::render()
core::matrix4 m;
SMD3QuaterionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList ( getFrameNr(),
SMD3QuaterionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList ( (s32)getFrameNr(),
255,
getStartFrame (),
getEndFrame ()
@ -394,6 +487,8 @@ void CAnimatedMeshSceneNode::render()
}
}
}
}
@ -489,39 +584,46 @@ IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(s32 id,
IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName)
{
if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
return 0;
checkJoints();
ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh;
s32 number = skinnedMesh->getJointNumber(jointName);
if (number == -1)
{
os::Printer::log("Joint with specified name not found in skinned mesh.", jointName, ELL_WARNING);
return 0;
}
if ((s32)JointChildSceneNodes.size() <= number)
{
os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING);
return 0;
}
return (IBoneSceneNode*)JointChildSceneNodes[number]; //JointChildSceneNodes will only be IBoneSceneNode later
}
//! Returns a pointer to a child node, which has the same transformation as
//! the corrsesponding joint, if the mesh in this scene node is a ms3d mesh.
ISceneNode* CAnimatedMeshSceneNode::getMS3DJointNode(const c8* jointName)
{
if (!Mesh || Mesh->getMeshType() != EAMT_MS3D)
return 0;
IAnimatedMeshMS3D* amm = (IAnimatedMeshMS3D*)Mesh;
s32 jointCount = amm->getJointCount();
s32 number = amm->getJointNumber(jointName);
//return getJointNode(jointName);
if (number == -1)
{
os::Printer::log("Joint with specified name not found in ms3d mesh.", jointName, ELL_WARNING);
return 0;
}
if (JointChildSceneNodes.empty())
{
// allocate joints for the first time.
JointChildSceneNodes.set_used(jointCount);
for (s32 i=0; i<jointCount; ++i)
JointChildSceneNodes[i] = 0;
}
if (JointChildSceneNodes[number] == 0)
{
JointChildSceneNodes[number] =
SceneManager->addDummyTransformationSceneNode(this);
JointChildSceneNodes[number]->grab();
}
return JointChildSceneNodes[number];
return 0;
}
@ -529,72 +631,12 @@ ISceneNode* CAnimatedMeshSceneNode::getMS3DJointNode(const c8* jointName)
//! the corrsesponding joint, if the mesh in this scene node is a ms3d mesh.
ISceneNode* CAnimatedMeshSceneNode::getXJointNode(const c8* jointName)
{
if (!Mesh || Mesh->getMeshType() != EAMT_X)
return 0;
//return getJointNode(jointName);
IAnimatedMeshX* amm = (IAnimatedMeshX*)Mesh;
s32 jointCount = amm->getJointCount();
s32 number = amm->getJointNumber(jointName);
if (number == -1)
{
os::Printer::log("Joint with specified name not found in x mesh.", jointName, ELL_WARNING);
return 0;
}
if (JointChildSceneNodes.empty())
{
// allocate joints for the first time.
JointChildSceneNodes.set_used(jointCount);
for (s32 i=0; i<jointCount; ++i)
JointChildSceneNodes[i] = 0;
}
if (JointChildSceneNodes[number] == 0)
{
JointChildSceneNodes[number] =
SceneManager->addDummyTransformationSceneNode(this);
JointChildSceneNodes[number]->grab();
}
return JointChildSceneNodes[number];
return 0;
}
//! Returns a pointer to a child node, which has the same transformation as
//! the corrsesponding joint, if the mesh in this scene node is a b3d mesh.
ISceneNode* CAnimatedMeshSceneNode::getB3DJointNode(const c8* jointName)
{
if (!Mesh || Mesh->getMeshType() != EAMT_B3D)
return 0;
IAnimatedMeshB3d* amm = (IAnimatedMeshB3d*)Mesh;
s32 jointCount = amm->getJointCount();
s32 number = amm->getJointNumber(jointName);
if (number == -1)
{
os::Printer::log("Joint with specified name not found in b3d mesh.", jointName, ELL_WARNING);
return 0;
}
if (JointChildSceneNodes.empty())
{
// allocate joints for the first time.
JointChildSceneNodes.set_used(jointCount);
for (s32 i=0; i<jointCount; ++i)
JointChildSceneNodes[i] = 0;
}
if (JointChildSceneNodes[number] == 0)
{
JointChildSceneNodes[number] =
SceneManager->addDummyTransformationSceneNode(this);
JointChildSceneNodes[number]->grab();
}
return JointChildSceneNodes[number];
}
//! Removes a child from this scene node.
//! Implemented here, to be able to remove the shadow properly, if there is one,
@ -608,17 +650,20 @@ bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child)
return true;
}
if (ISceneNode::removeChild(child))
if (JointsUsed) //stop it doing weird things while the joints are being made
{
for (s32 i=0; i<(s32)JointChildSceneNodes.size(); ++i)
if (JointChildSceneNodes[i] == child)
if (ISceneNode::removeChild(child))
{
JointChildSceneNodes[i]->drop();
JointChildSceneNodes[i] = 0;
for (s32 i=0; i<(s32)JointChildSceneNodes.size(); ++i)
if (JointChildSceneNodes[i] == child)
{
//JointChildSceneNodes[i]->drop();
JointChildSceneNodes[i] = 0;
return true;
}
return true;
}
return true;
}
return false;
@ -804,7 +849,7 @@ void CAnimatedMeshSceneNode::updateAbsolutePosition()
SMD3QuaterionTag relative( RelativeTranslation, RelativeRotation );
SMD3QuaterionTagList *taglist;
taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( getFrameNr(),255,getStartFrame (),getEndFrame () );
taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( (s32)getFrameNr(),255,getStartFrame (),getEndFrame () );
if ( taglist )
{
MD3Special.AbsoluteTagList.Container.set_used ( taglist->size () );
@ -818,6 +863,166 @@ void CAnimatedMeshSceneNode::updateAbsolutePosition()
}
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
void CAnimatedMeshSceneNode::setJointMode(s32 mode)
{
checkJoints();
if (mode<0) mode=0;
if (mode>3) mode=3;
JointMode=mode;
}
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
void CAnimatedMeshSceneNode::setTransitionTime(f32 Time)
{
if (Time!=0) checkJoints();
if (!(JointMode &2)) setJointMode(2);
TransitionTime=u32(Time*1000.0f);
}
//! updates the joint positions of this mesh
void CAnimatedMeshSceneNode::animateJoints()
{
checkJoints();
if (Mesh && Mesh->getMeshType() == EAMT_SKINNED )
{
if (JointsUsed)
{
f32 frame = getFrameNr(); //old?
ISkinnedMesh* skinnedMesh=(ISkinnedMesh*)Mesh;
skinnedMesh->animateMesh(frame, 1.0f);
skinnedMesh->recoverJointsFromMesh( JointChildSceneNodes);
//---slow---
for (u32 n=0;n<JointChildSceneNodes.size();++n)
if (JointChildSceneNodes[n]->getParent()==this)
{
JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option
}
//-----------------------------------------
// Transition
//-----------------------------------------
if (Transiting!=0)
{
u32 n;
//Check the array is big enough (not really needed)
if (PretransitingSave.size()<JointChildSceneNodes.size())
{
for(n=PretransitingSave.size();n<JointChildSceneNodes.size();++n)
PretransitingSave.push_back(core::matrix4());
}
f32 InvTransitingBlend=1-TransitingBlend;
for (n=0;n<JointChildSceneNodes.size();++n)
{
//------Position------
JointChildSceneNodes[n]->setPosition(PretransitingSave[n].getTranslation()*InvTransitingBlend+
JointChildSceneNodes[n]->getPosition()*TransitingBlend);
//------Rotation------
//Code is slow, needs to be fixed up
core::quaternion RotationStart, RotationEnd;
core::quaternion QRotation;
core::vector3df tmpVector;
tmpVector=PretransitingSave[n].getRotationDegrees();
RotationStart.set(tmpVector.X*core::DEGTORAD ,tmpVector.Y*core::DEGTORAD,tmpVector.Z*core::DEGTORAD);
tmpVector=JointChildSceneNodes[n]->getRotation();
RotationEnd.set(tmpVector.X*core::DEGTORAD ,tmpVector.Y*core::DEGTORAD,tmpVector.Z*core::DEGTORAD);
QRotation.slerp(RotationStart, RotationEnd, TransitingBlend);
QRotation.toEuler (tmpVector);
tmpVector.X*=core::RADTODEG; tmpVector.Y*=core::RADTODEG; tmpVector.Z*=core::RADTODEG; //convert from radians back to degrees
JointChildSceneNodes[n]->setRotation( tmpVector );
//------Scale------
//JointChildSceneNodes[n]->setScale(PretransitingSave[n].getScale()*InvTransitingBlend+
// JointChildSceneNodes[n]->getScale()*TransitingBlend);
}
}
}
}
}
void CAnimatedMeshSceneNode::checkJoints()
{
if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
return;
if (!JointsUsed)
{
//Create joints for SkinnedMesh
((ISkinnedMesh*)Mesh)->createJoints( JointChildSceneNodes,this,SceneManager);
((ISkinnedMesh*)Mesh)->recoverJointsFromMesh( JointChildSceneNodes);
JointsUsed=true;
JointMode=1;
}
}
void CAnimatedMeshSceneNode::beginTransition()
{
if (!JointsUsed) return;
u32 n;
if (TransitionTime!=0)
{
//Check the array is big enough
if (PretransitingSave.size()<JointChildSceneNodes.size())
{
for(n=PretransitingSave.size();n<JointChildSceneNodes.size();++n)
PretransitingSave.push_back(core::matrix4());
}
//Copy the position of joints
for (n=0;n<JointChildSceneNodes.size();++n)
PretransitingSave[n]=JointChildSceneNodes[n]->getRelativeTransformation();
Transiting=1.0f/f32(TransitionTime);
}
}
} // end namespace scene
} // end namespace irr

View File

@ -8,6 +8,9 @@
#include "IAnimatedMeshSceneNode.h"
#include "IAnimatedMesh.h"
#include "matrix4.h"
namespace irr
{
namespace scene
@ -28,7 +31,7 @@ namespace scene
virtual ~CAnimatedMeshSceneNode();
//! sets the current frame. from now on the animation is played from this frame.
virtual void setCurrentFrame(s32 frame);
virtual void setCurrentFrame(f32 frame);
//! frame
virtual void OnRegisterSceneNode();
@ -72,6 +75,10 @@ namespace scene
virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id,
bool zfailmethod=true, f32 infinity=10000.0f);
//! Returns a pointer to a child node, which has the same transformation as
//! the corrsesponding joint, if the mesh in this scene node is a skinned mesh.
virtual IBoneSceneNode* getJointNode(const c8* jointName);
//! Returns a pointer to a child node, which has the same transformation as
//! the corrsesponding joint, if the mesh in this scene node is a ms3d mesh.
virtual ISceneNode* getMS3DJointNode(const c8* jointName);
@ -80,10 +87,6 @@ namespace scene
//! the corrsesponding joint, if the mesh in this scene node is a x mesh.
virtual ISceneNode* getXJointNode(const c8* jointName);
//! Returns a pointer to a child node, which has the same transformation as
//! the corresponding joint, if the mesh in this scene node is a b3d mesh.
virtual ISceneNode* getB3DJointNode(const c8* jointName);
//! Removes a child from this scene node.
//! Implemented here, to be able to remove the shadow properly, if there is one,
//! or to remove attached childs.
@ -96,7 +99,7 @@ namespace scene
virtual bool setMD2Animation(const c8* animationName);
//! Returns the current displayed frame number.
virtual s32 getFrameNr() const;
virtual f32 getFrameNr() const;
//! Returns the current start frame number.
virtual s32 getStartFrame() const;
//! Returns the current end frame number.
@ -132,9 +135,24 @@ namespace scene
//! updates the absolute position based on the relative and the parents position
virtual void updateAbsolutePosition();
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
virtual void setJointMode(s32 mode);
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
virtual void setTransitionTime(f32 Time);
//! updates the joint positions of this mesh
virtual void animateJoints();
private:
u32 buildFrameNr( u32 timeMs);
f32 buildFrameNr( u32 timeMs);
void checkJoints();
void beginTransition();
core::array<video::SMaterial> Materials;
core::aabbox3d<f32> Box;
@ -145,7 +163,15 @@ namespace scene
s32 EndFrame;
f32 FramesPerSecond;
s32 CurrentFrameNr;
f32 CurrentFrameNr;
s32 JointMode; //0-unused, 1-get joints only, 2-set joints only, 3-move and set
bool JointsUsed;
u32 TransitionTime; //Transition time in millisecs
f32 Transiting; //is mesh transiting (plus cache of TransitionTime)
f32 TransitingBlend; //0-1, calculated on buildFrameNr
bool Looping;
bool ReadOnlyMaterials;
@ -155,7 +181,9 @@ namespace scene
IShadowVolumeSceneNode* Shadow;
core::array<IDummyTransformationSceneNode* > JointChildSceneNodes;
core::array<IBoneSceneNode* > JointChildSceneNodes;
core::array<core::matrix4> PretransitingSave;
struct SMD3Special
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
// B3D mesh loader
#include "IrrCompileConfig.h"
#ifndef __C_B3D_MESH_LOADER_H_INCLUDED__
#define __C_B3D_MESH_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "ISceneManager.h"
#include "CSkinnedMesh.h"
#include "IReadFile.h"
namespace irr
{
namespace scene
{
//! Meshloader for B3D format
class CB3DMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CB3DMeshFileLoader(scene::ISceneManager* smgr);
//! destructor
virtual ~CB3DMeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const c8* fileName);
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
struct SB3dChunkHeader
{
c8 name[4];
s32 size;
};
struct SB3dChunk
{
c8 name[4];
s32 length;
s32 startposition;
};
struct SB3dTexture
{
irr::video::ITexture* Texture;
s32 Flags;
s32 Blend;
f32 Xpos;
f32 Ypos;
f32 Xscale;
f32 Yscale;
f32 Angle;
};
struct SB3dMaterial
{
irr::video::SMaterial* Material;
f32 red, green, blue, alpha;
f32 shininess;
s32 blend,fx;
SB3dTexture *Textures[2];
};
bool load();
bool readChunkNODE(CSkinnedMesh::SJoint* InJoint);
bool readChunkMESH(CSkinnedMesh::SJoint* InJoint);
bool readChunkVRTS(CSkinnedMesh::SJoint* InJoint, scene::SSkinMeshBuffer *MeshBuffer, s32 Vertices_Start);
bool readChunkTRIS(CSkinnedMesh::SJoint* InJoint, scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
bool readChunkBONE(CSkinnedMesh::SJoint* InJoint);
bool readChunkKEYS(CSkinnedMesh::SJoint* InJoint);
bool readChunkANIM(CSkinnedMesh::SJoint* InJoint);
bool readChunkTEXS();
bool readChunkBRUS();
core::stringc readString();
core::stringc stripPathFromString(core::stringc string, bool returnPath=false);
void readFloats(f32* vec, u32 count);
core::array<SB3dChunk> B3dStack;
bool NormalsInFile;
core::array<SB3dMaterial> Materials;
core::array<SB3dTexture> Textures;
core::array<s32> AnimatedVertices_VertexID;
core::array<s32> AnimatedVertices_BufferID;
core::array<video::S3DVertex2TCoords*> BaseVertices;
core::array<scene::SSkinMeshBuffer*> *Buffers;
core::array<CSkinnedMesh::SJoint*> *AllJoints;
//
ISceneManager* SceneManager;
CSkinnedMesh* AnimatedMesh;
io::IReadFile* file;
};
} // end namespace scene
} // end namespace irr
#endif // __C_B3D_MESH_LOADER_H_INCLUDED__

View File

@ -0,0 +1,87 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
#include "CBSPMeshFileLoader.h"
#include "CQ3LevelMesh.h"
namespace irr
{
namespace scene
{
//! Constructor
CBSPMeshFileLoader::CBSPMeshFileLoader(io::IFileSystem* fs,video::IVideoDriver* driver, scene::ISceneManager* smgr)
: FileSystem(fs), Driver(driver), SceneManager(smgr)
{
if (FileSystem)
FileSystem->grab();
if (Driver)
Driver->grab();
}
//! destructor
CBSPMeshFileLoader::~CBSPMeshFileLoader()
{
if (FileSystem)
FileSystem->drop();
if (Driver)
Driver->drop();
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool CBSPMeshFileLoader::isALoadableFileExtension(const c8* filename)
{
return strstr(filename, ".bsp") || strstr(filename, ".shader");
}
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
IAnimatedMesh* CBSPMeshFileLoader::createMesh(irr::io::IReadFile* file)
{
// load quake 3 bsp
if (strstr(file->getFileName(), ".bsp"))
{
CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager);
q->getShader ( "scripts/models.shader", 1 );
q->getShader ( "scripts/liquid.shader", 1 );
//q->getShader ( "scripts/sky.shader", 1 );
if ( q->loadFile(file) )
return q;
q->drop();
}
// load quake 3 shader container
if (strstr(file->getFileName(), ".shader"))
{
CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager);
q->getShader ( file->getFileName(), 1 );
return q;
}
return 0;
}
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BSP_LOADER_

View File

@ -2,8 +2,8 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_DEFAULT_MESH_FORMAT_LOADER_H_INCLUDED__
#define __C_DEFAULT_MESH_FORMAT_LOADER_H_INCLUDED__
#ifndef __C_BSP_MESH_FILE_LOADER_H_INCLUDED__
#define __C_BSP_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "IFileSystem.h"
@ -15,17 +15,16 @@ namespace irr
namespace scene
{
//! Meshloader capable of loading all Irrlicht default build in formats.
/** Which are: Quake 3 Bsp level, Quake 2 MD2 model, Milkshape .ms3d model. */
class CDefaultMeshFormatLoader : public IMeshLoader
//! Meshloader capable of loading Quake 3 BSP files and shaders
class CBSPMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CDefaultMeshFormatLoader(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr);
CBSPMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr);
//! destructor
virtual ~CDefaultMeshFormatLoader();
virtual ~CBSPMeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")

View File

@ -0,0 +1,124 @@
#include "CBoneSceneNode.h"
namespace irr
{
namespace scene
{
//! constructor
CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
u32 boneIndex, const c8* boneName)
: IBoneSceneNode(parent, mgr, id), AnimationMode(EBAM_AUTOMATIC),
BoneIndex(boneIndex), BoneName(boneName)
{
}
//! destructor
CBoneSceneNode::~CBoneSceneNode()
{
}
//! Returns the name of the bone
const c8* CBoneSceneNode::getBoneName() const
{
return BoneName.c_str();
}
//! Returns the index of the bone
u32 CBoneSceneNode::getBoneIndex() const
{
return BoneIndex;
}
//! Sets the animation mode of the bone. Returns true if successful.
bool CBoneSceneNode::setAnimationMode(E_BONE_ANIMATION_MODE mode)
{
AnimationMode = mode;
return true;
}
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE CBoneSceneNode::getAnimationMode() const
{
return AnimationMode;
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CBoneSceneNode::getBoundingBox() const
{
return Box;
}
/*
//! Returns the relative transformation of the scene node.
core::matrix4 CBoneSceneNode::getRelativeTransformation() const
{
return core::matrix4(); // RelativeTransformation;
}
*/
void CBoneSceneNode::OnAnimate(u32 timeMs)
{
if (IsVisible)
{
// animate this node with all animators
core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
for (; ait != Animators.end(); ++ait)
(*ait)->animateNode(this, timeMs);
// update absolute position
//updateAbsolutePosition();
// perform the post render process on all children
core::list<ISceneNode*>::Iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
}
void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node)
{
Node->updateAbsolutePosition();
core::list<ISceneNode*>::Iterator it = Node->getChildren().begin();
for (; it != Node->getChildren().end(); ++it)
{
helper_updateAbsolutePositionOfAllChildren( (*it) );
}
}
void CBoneSceneNode::updateAbsolutePositionOfAllChildren()
{
helper_updateAbsolutePositionOfAllChildren( this );
}
void CBoneSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
{
out->addInt("BoneIndex", BoneIndex);
out->addString("BoneName", BoneName.c_str());
out->addEnum("AnimationMode", AnimationMode, BoneAnimationModeNames);
}
void CBoneSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
BoneIndex = in->getAttributeAsInt("BoneIndex");
BoneName = in->getAttributeAsString("BoneName");
AnimationMode = (E_BONE_ANIMATION_MODE)in->getAttributeAsEnumeration("AnimationMode", BoneAnimationModeNames);
// todo: add/replace bone in parent with bone from mesh
}
} // namespace scene
} // namespace irr

View File

@ -0,0 +1,71 @@
#ifndef __C_BONE_SCENE_NODE_H_INCLUDED__
#define __C_BONE_SCENE_NODE_H_INCLUDED__
// Used with SkinnedMesh and IAnimatedMeshSceneNode, for boned meshes
#include "IBoneSceneNode.h"
#include "irrString.h"
namespace irr
{
namespace scene
{
class CBoneSceneNode : public IBoneSceneNode
{
public:
//! constructor
CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr,
s32 id=-1, u32 boneIndex=0, const c8* boneName=0);
//! destructor
~CBoneSceneNode();
//! Returns the name of the bone
virtual const c8* getBoneName() const;
//! Returns the index of the bone
virtual u32 getBoneIndex() const;
//! Sets the animation mode of the bone. Returns true if successful.
virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode);
//! Gets the current animation mode of the bone
virtual E_BONE_ANIMATION_MODE getAnimationMode() const;
//! returns the axis aligned bounding box of this node
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! Returns the relative transformation of the scene node.
//virtual core::matrix4 getRelativeTransformation() const;
virtual void OnAnimate(u32 timeMs);
void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node);
virtual void updateAbsolutePositionOfAllChildren();
//! Writes attributes of the scene node.
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0);
//! Reads attributes of the scene node.
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);
private:
E_BONE_ANIMATION_MODE AnimationMode;
u32 BoneIndex;
core::stringc BoneName;
core::aabbox3d<f32> Box;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -5,6 +5,9 @@
// This file was written by Saurav Mohapatra and modified by Nikolaus Gebhardt.
// See CCSMLoader.h for details.
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
#include "CCSMLoader.h"
#include "os.h"
#include "IFileSystem.h"
@ -871,3 +874,4 @@ namespace scene
} // end namespace
} // end namespace
#endif // _IRR_COMPILE_WITH_CSM_LOADER_

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
#include "CColladaFileLoader.h"
#include "os.h"
#include "IXMLReader.h"
@ -1564,3 +1567,4 @@ void CColladaFileLoader::uriToId(core::stringc& str)
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_COLLADA_LOADER_

View File

@ -13,6 +13,9 @@
See the header file for additional information including use and distribution rights.
*/
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
#include "CDMFLoader.h"
#include "ISceneManager.h"
#include "IAttributes.h"
@ -441,3 +444,5 @@ bool CDMFLoader::isALoadableFileExtension(const c8* filename)
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_DMF_LOADER_

View File

@ -1,131 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CDefaultMeshFormatLoader.h"
#include "CAnimatedMeshMD2.h"
#include "CAnimatedMeshMS3D.h"
#include "CQ3LevelMesh.h"
#include "CAnimatedMeshB3d.h"
namespace irr
{
namespace scene
{
//! Constructor
CDefaultMeshFormatLoader::CDefaultMeshFormatLoader(io::IFileSystem* fs,video::IVideoDriver* driver, scene::ISceneManager* smgr)
: FileSystem(fs), Driver(driver), SceneManager(smgr)
{
if (FileSystem)
FileSystem->grab();
if (Driver)
Driver->grab();
}
//! destructor
CDefaultMeshFormatLoader::~CDefaultMeshFormatLoader()
{
if (FileSystem)
FileSystem->drop();
if (Driver)
Driver->drop();
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool CDefaultMeshFormatLoader::isALoadableFileExtension(const c8* filename)
{
return strstr(filename, ".md2") || strstr(filename, ".b3d") ||
strstr(filename, ".ms3d") || strstr(filename, ".bsp") ||
strstr(filename, ".shader");
}
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
IAnimatedMesh* CDefaultMeshFormatLoader::createMesh(irr::io::IReadFile* file)
{
IAnimatedMesh* msh = 0;
// This method loads a mesh if it cans.
// Someday I will have to refactor this, and split the DefaultMeshFormatloader
// into one loader for every format.
bool success = false;
// load quake 2 md2 model
if (strstr(file->getFileName(), ".md2"))
{
msh = new CAnimatedMeshMD2();
success = ((CAnimatedMeshMD2*)msh)->loadFile(file);
if (success)
return msh;
msh->drop();
}
// load milkshape
if (strstr(file->getFileName(), ".ms3d"))
{
msh = new CAnimatedMeshMS3D(Driver);
success = ((CAnimatedMeshMS3D*)msh)->loadFile(file);
if (success)
return msh;
msh->drop();
}
// load quake 3 bsp
if (strstr(file->getFileName(), ".bsp"))
{
CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager);
q->getShader ( "scripts/models.shader", 1 );
q->getShader ( "scripts/liquid.shader", 1 );
//q->getShader ( "scripts/sky.shader", 1 );
if ( q->loadFile(file) )
return q;
q->drop();
}
// load quake 3 shader container
if (strstr(file->getFileName(), ".shader"))
{
CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager);
q->getShader ( file->getFileName(), 1 );
return q;
}
// load blitz basic
if (strstr(file->getFileName(), ".b3d"))
{
file->seek(0);
msh = new CAnimatedMeshB3d(Driver);
success = ((CAnimatedMeshB3d*)msh)->loadFile(file);
if (success)
return msh;
msh->drop();
}
return 0;
}
} // end namespace scene
} // end namespace irr

View File

@ -74,6 +74,9 @@ Version 1.0 - 29 July 2004
*/
//////////////////////////////////////////////////////////////////////
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
#include "SMeshBufferLightMap.h"
#include "SAnimatedMesh.h"
#include "SMeshBuffer.h"
@ -354,3 +357,5 @@ void CLMTSMeshFileLoader::loadTextures()
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_LMTS_LOADER_

View File

@ -0,0 +1,54 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
#include "CMD2MeshFileLoader.h"
#include "CAnimatedMeshMD2.h"
namespace irr
{
namespace scene
{
//! Constructor
CMD2MeshFileLoader::CMD2MeshFileLoader()
{
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool CMD2MeshFileLoader::isALoadableFileExtension(const c8* filename)
{
return strstr(filename, ".md2")!=0;
}
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
IAnimatedMesh* CMD2MeshFileLoader::createMesh(irr::io::IReadFile* file)
{
IAnimatedMesh* msh = 0;
bool success = false;
msh = new CAnimatedMeshMD2();
success = ((CAnimatedMeshMD2*)msh)->loadFile(file);
if (success)
return msh;
msh->drop();
return 0;
}
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_MD2_LOADER_

View File

@ -0,0 +1,39 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_MD2_MESH_FILE_LOADER_H_INCLUDED__
#define __C_MD2_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
namespace irr
{
namespace scene
{
//! Meshloader capable of loading MD2 files
class CMD2MeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CMD2MeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const c8* fileName);
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
virtual IAnimatedMesh* createMesh(irr::io::IReadFile* file);
};
} // end namespace scene
} // end namespace irr
#endif // __C_MD2_MESH_LOADER_H_INCLUDED__

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
#include "CMD3MeshFileLoader.h"
#include "CAnimatedMeshMD3.h"
#include "irrString.h"
@ -47,3 +50,4 @@ IAnimatedMesh* CMD3MeshFileLoader::createMesh(irr::io::IReadFile* file)
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_MD3_LOADER_

View File

@ -0,0 +1,605 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
#include "IReadFile.h"
#include "os.h"
#include "CMS3DMeshFileLoader.h"
#include "CSkinnedMesh.h"
namespace irr
{
namespace scene
{
// byte-align structures
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
// File header
struct MS3DHeader
{
c8 ID[10];
s32 Version;
} PACK_STRUCT;
// Vertex information
struct MS3DVertex
{
u8 Flags;
f32 Vertex[3];
s8 BoneID;
u8 RefCount;
} PACK_STRUCT;
// Triangle information
struct MS3DTriangle
{
u16 Flags;
u16 VertexIndices[3];
f32 VertexNormals[3][3];
f32 S[3], T[3];
u8 SmoothingGroup;
u8 GroupIndex;
} PACK_STRUCT;
// Material information
struct MS3DMaterial
{
s8 Name[32];
f32 Ambient[4];
f32 Diffuse[4];
f32 Specular[4];
f32 Emissive[4];
f32 Shininess; // 0.0f - 128.0f
f32 Transparency; // 0.0f - 1.0f
u8 Mode; // 0, 1, 2 is unused now
s8 Texture[128];
s8 Alphamap[128];
} PACK_STRUCT;
// Joint information
struct MS3DJoint
{
u8 Flags;
s8 Name[32];
s8 ParentName[32];
f32 Rotation[3];
f32 Translation[3];
u16 NumRotationKeyframes;
u16 NumTranslationKeyframes;
} PACK_STRUCT;
// Keyframe data
struct MS3DKeyframe
{
f32 Time;
f32 Parameter[3];
} PACK_STRUCT;
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
//! Constructor
CMS3DMeshFileLoader::CMS3DMeshFileLoader(video::IVideoDriver *driver)
: Driver(driver), AnimatedMesh(0)
{
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool CMS3DMeshFileLoader::isALoadableFileExtension(const c8* filename)
{
return strstr(filename, ".ms3d")!=0;
}
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
IAnimatedMesh* CMS3DMeshFileLoader::createMesh(irr::io::IReadFile* file)
{
if (!file)
return 0;
AnimatedMesh = new CSkinnedMesh();
if ( load(file) )
{
AnimatedMesh->finalize();
}
else
{
AnimatedMesh->drop();
AnimatedMesh = 0;
}
return AnimatedMesh;
}
//! loads an md2 file
bool CMS3DMeshFileLoader::load(io::IReadFile* file)
{
if (!file)
return false;
// find file size
s32 fileSize = file->getSize();
// read whole file
u8* buffer = new u8[fileSize];
s32 read = file->read(buffer, fileSize);
if (read != fileSize)
{
delete [] buffer;
os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR);
return false;
}
// read header
const u8 *pPtr = (u8*)((void*)buffer);
MS3DHeader *pHeader = (MS3DHeader*)pPtr;
pPtr += sizeof(MS3DHeader);
if ( strncmp( pHeader->ID, "MS3D000000", 10 ) != 0 )
{
delete [] buffer;
os::Printer::log("Not a valid Milkshape3D Model File. Loading failed", file->getFileName(), ELL_ERROR);
return false;
}
#ifdef __BIG_ENDIAN__
pHeader->Version = os::Byteswap::byteswap(pHeader->Version);
#endif
if ( pHeader->Version < 3 || pHeader->Version > 4 )
{
delete [] buffer;
os::Printer::log("Only Milkshape3D version 1.3 and 1.4 is supported. Loading failed", file->getFileName(), ELL_ERROR);
return false;
}
// get pointers to data
// vertices
u16 numVertices = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numVertices = os::Byteswap::byteswap(numVertices);
#endif
pPtr += sizeof(u16);
MS3DVertex *vertices = (MS3DVertex*)pPtr;
pPtr += sizeof(MS3DVertex) * numVertices;
#ifdef __BIG_ENDIAN__
for (u16 tmp=0; tmp<numVertices; ++tmp)
for (u16 j=0; j<3; ++j)
vertices[i].Vertex[j] = os::Byteswap::byteswap(vertices[i].Vertex[j]);
#endif
// triangles
u16 numTriangles = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numTriangles = os::Byteswap::byteswap(numTriangles);
#endif
pPtr += sizeof(u16);
MS3DTriangle *triangles = (MS3DTriangle*)pPtr;
pPtr += sizeof(MS3DTriangle) * numTriangles;
#ifdef __BIG_ENDIAN__
for (u16 tmp=0; tmp<numTriangles; ++tmp)
{
triangles[tmp].Flags = os::Byteswap::byteswap(triangles[tmp].Flags);
for (u16 j=0; j<3; ++j)
{
triangles[tmp].VertexIndices[j] = os::Byteswap::byteswap(triangles[tmp].VertexIndices[j]);
for (u16 k=0; k<3; ++k)
triangles[tmp].VertexNormals[j][k] = os::Byteswap::byteswap(triangles[tmp].VertexNormals[j][k]);
triangles[tmp].S[j] = os::Byteswap::byteswap(triangles[tmp].S[j]);
triangles[tmp].T[j] = os::Byteswap::byteswap(triangles[tmp].T[j]);
}
}
#endif
// groups
u16 numGroups = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numGroups = os::Byteswap::byteswap(numGroups);
#endif
pPtr += sizeof(u16);
//skip groups
u32 i;
for (i=0; i<numGroups; ++i)
{
Groups.push_back(SGroup());
SGroup& grp = Groups.getLast();
// The byte flag is before the name, so add 1
grp.Name = ((const c8*) pPtr) + 1;
pPtr += 33; // name and 1 byte flags
u16 triangleCount = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
triangleCount = os::Byteswap::byteswap(triangleCount);
#endif
pPtr += sizeof(u16);
//pPtr += sizeof(u16) * triangleCount; // triangle indices
for (u16 j=0; j<triangleCount; ++j)
{
#ifdef __BIG_ENDIAN__
grp.VertexIds.push_back(os::Byteswap::byteswap(*(u16*)pPtr));
#else
grp.VertexIds.push_back(*(u16*)pPtr);
#endif
pPtr += sizeof (u16);
}
grp.MaterialIdx = *(u8*)pPtr;
if (grp.MaterialIdx == 255)
grp.MaterialIdx = 0;
pPtr += sizeof(c8); // material index
}
// skip materials
u16 numMaterials = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
numMaterials = os::Byteswap::byteswap(numMaterials);
#endif
pPtr += sizeof(u16);
// MS3DMaterial *materials = (MS3DMaterial*)pPtr;
// pPtr += sizeof(MS3DMaterial) * numMaterials;
if(numMaterials <= 0)
{
// if there are no materials, add at least one buffer
AnimatedMesh->createBuffer();
}
for (i=0; i<numMaterials; ++i)
{
MS3DMaterial *material = (MS3DMaterial*)pPtr;
#ifdef __BIG_ENDIAN__
for (u16 j=0; j<4; ++j)
material->Ambient[j] = os::Byteswap::byteswap(material->Ambient[j]);
for (u16 j=0; j<4; ++j)
material->Diffuse[j] = os::Byteswap::byteswap(material->Diffuse[j]);
for (u16 j=0; j<4; ++j)
material->Specular[j] = os::Byteswap::byteswap(material->Specular[j]);
for (u16 j=0; j<4; ++j)
material->Emissive[j] = os::Byteswap::byteswap(material->Emissive[j]);
material->Shininess = os::Byteswap::byteswap(material->Shininess);
material->Transparency = os::Byteswap::byteswap(material->Transparency);
#endif
pPtr += sizeof(MS3DMaterial);
scene::SSkinMeshBuffer *tmpBuffer = AnimatedMesh->createBuffer();
tmpBuffer->Material.MaterialType = video::EMT_SOLID;
tmpBuffer->Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor ();
tmpBuffer->Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor ();
tmpBuffer->Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor ();
tmpBuffer->Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor ();
tmpBuffer->Material.Shininess = material->Shininess;
core::stringc TexturePath=(const c8*)material->Texture;
TexturePath.trim();
if (TexturePath!="")
{
TexturePath=stripPathFromString(file->getFileName(),true) + stripPathFromString(TexturePath,false);
tmpBuffer->Material.Textures[0] = Driver->getTexture(TexturePath.c_str() );
}
core::stringc AlphamapPath=(const c8*)material->Alphamap;
AlphamapPath.trim();
if (AlphamapPath!="")
{
AlphamapPath=stripPathFromString(file->getFileName(),true) + stripPathFromString(AlphamapPath,false);
tmpBuffer->Material.Textures[2] = Driver->getTexture(AlphamapPath.c_str() );
}
}
// animation time
f32 framesPerSecond = *(f32*)pPtr;
#ifdef __BIG_ENDIAN__
framesPerSecond = os::Byteswap::byteswap(framesPerSecond);
#endif
pPtr += sizeof(f32) * 2; // fps and current time
if (framesPerSecond==0)
framesPerSecond=1;
s32 frameCount = *(s32*)pPtr;
#ifdef __BIG_ENDIAN__
frameCount = os::Byteswap::byteswap(frameCount);
#endif
pPtr += sizeof(s32);
u16 jointCount = *(u16*)pPtr;
#ifdef __BIG_ENDIAN__
jointCount = os::Byteswap::byteswap(jointCount);
#endif
pPtr += sizeof(u16);
core::array<core::stringc> ParentNames;
// load joints
for (i=0; i<jointCount; ++i)
{
u32 j;
MS3DJoint *pJoint = (MS3DJoint*)pPtr;
#ifdef __BIG_ENDIAN__
for (j=0; j<3; ++j)
pJoint->Rotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]);
for (j=0; j<3; ++j)
pJoint->Translation[j] = os::Byteswap::byteswap(pJoint->Translation[j]);
pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes);
pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes);
#endif
pPtr += sizeof(MS3DJoint);
ISkinnedMesh::SJoint *jnt = AnimatedMesh->createJoint();
/*
jnt.Name = pJoint->Name;
jnt.Index = i;
jnt.Rotation.X = pJoint->Rotation[0];
jnt.Rotation.Y = pJoint->Rotation[1];
jnt.Rotation.Z = pJoint->Rotation[2];
jnt.Translation.X = pJoint->Translation[0];
jnt.Translation.Y = pJoint->Translation[1];
jnt.Translation.Z = pJoint->Translation[2];
jnt.ParentName = pJoint->ParentName;
jnt.Parent = -1;
*/
jnt->Name = pJoint->Name;
jnt->LocalMatrix.makeIdentity();
jnt->LocalMatrix.setRotationRadians(
core::vector3df(pJoint->Rotation[0], pJoint->Rotation[1], pJoint->Rotation[2]) );
jnt->LocalMatrix.setTranslation(
core::vector3df(pJoint->Translation[0], pJoint->Translation[1], pJoint->Translation[2]) );
ParentNames.push_back( (c8*)pJoint->ParentName );
/*if (pJoint->NumRotationKeyframes ||
pJoint->NumTranslationKeyframes)
HasAnimation = true;*/
// get rotation keyframes
for (j=0; j < pJoint->NumRotationKeyframes; ++j)
{
MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
#ifdef __BIG_ENDIAN__
kf->Time = os::Byteswap::byteswap(kf->Time);
for (u32 l=0; l<3; ++l)
kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
#endif
pPtr += sizeof(MS3DKeyframe);
ISkinnedMesh::SRotationKey *k=AnimatedMesh->createRotationKey(jnt);
k->frame = kf->Time * framesPerSecond;
core::matrix4 tmpMatrix;
tmpMatrix.setRotationRadians(
core::vector3df(kf->Parameter[0], kf->Parameter[1], kf->Parameter[2]) );
tmpMatrix=jnt->LocalMatrix*tmpMatrix;
k->rotation = core::quaternion(tmpMatrix);
//fix
//k->rotation = core::vector3df
// (kf->Parameter[0],//+pJoint->Rotation[0]*core::RADTODEG,
// kf->Parameter[1],//+pJoint->Rotation[1]*core::RADTODEG,
// kf->Parameter[2]);//+pJoint->Rotation[2]*core::RADTODEG);
}
// get translation keyframes
for (j=0; j<pJoint->NumTranslationKeyframes; ++j)
{
MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
#ifdef __BIG_ENDIAN__
kf->Time = os::Byteswap::byteswap(kf->Time);
for (u32 l=0; l<3; ++l)
kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]);
#endif
pPtr += sizeof(MS3DKeyframe);
ISkinnedMesh::SPositionKey *k=AnimatedMesh->createPositionKey(jnt);
k->frame = kf->Time * framesPerSecond;
k->position = core::vector3df
(kf->Parameter[0]+pJoint->Translation[0],
kf->Parameter[1]+pJoint->Translation[1],
kf->Parameter[2]+pJoint->Translation[2]);
}
}
//find parent of every joint
for (u32 jointnum=0; jointnum<AnimatedMesh->getAllJoints().size(); ++jointnum)
{
for (u32 j2=0; j2<AnimatedMesh->getAllJoints().size(); ++j2)
{
if (jointnum != j2 && ParentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name )
{
AnimatedMesh->getAllJoints()[j2]->Children.push_back(AnimatedMesh->getAllJoints()[jointnum]);
break;
}
}
}
/*if (Joints[jointnum].Parent == -1)
os::Printer::log("Found joint in model without parent.", ELL_WARNING);*/
// create vertices and indices, attach them to the joints.
video::S3DVertex v;
core::array<video::S3DVertex> *Vertices;
core::array<u16> Indices;
for (i=0; i<numTriangles; ++i)
{
u32 tmp = Groups[triangles[i].GroupIndex].MaterialIdx;
Vertices = &AnimatedMesh->getMeshBuffers()[tmp]->Vertices_Standard;
for (u16 j = 0; j<3; ++j)
{
v.TCoords.X = triangles[i].S[j];
v.TCoords.Y = triangles[i].T[j];
v.Normal.X = triangles[i].VertexNormals[j][0];
v.Normal.Y = triangles[i].VertexNormals[j][1];
v.Normal.Z = triangles[i].VertexNormals[j][2];
if(triangles[i].GroupIndex < Groups.size() && Groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size())
v.Color = AnimatedMesh->getMeshBuffers()[Groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor;
else
v.Color.set(255,255,255,255);
v.Pos.X = vertices[triangles[i].VertexIndices[j]].Vertex[0];
v.Pos.Y = vertices[triangles[i].VertexIndices[j]].Vertex[1];
v.Pos.Z = vertices[triangles[i].VertexIndices[j]].Vertex[2];
// check if we already have this vertex in our vertex array
s32 index = -1;
for (u32 iV = 0; iV < Vertices->size(); ++iV)
{
if (v == (*Vertices)[iV])
{
index = (s32)iV;
break;
}
}
if (index == -1)
{
s32 boneid = vertices[triangles[i].VertexIndices[j]].BoneID;
if (boneid>=0 && boneid<(s32)AnimatedMesh->getAllJoints().size())
{
ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]);
w->buffer_id = Groups[triangles[i].GroupIndex].MaterialIdx;
w->strength = 1.0f;
w->vertex_id = Vertices->size();
//Joints[boneid]->VertexIds.push_back(Vertices.size());
}
Vertices->push_back(v);
index = Vertices->size() - 1;
}
Indices.push_back(index);
}
}
//create groups
s32 iIndex = -1;
for (i=0; i<Groups.size(); ++i)
{
SGroup& grp = Groups[i];
if (grp.MaterialIdx >= AnimatedMesh->getMeshBuffers().size())
grp.MaterialIdx = 0;
core::array<u16>& indices = AnimatedMesh->getMeshBuffers()[grp.MaterialIdx]->Indices;
for (u32 k=0; k < grp.VertexIds.size(); ++k)
for (u32 l=0; l<3; ++l)
indices.push_back(Indices[++iIndex]);
}
// calculate bounding box
/*
// inverse translate and rotate all vertices for making animation easier
if (HasAnimation)
for (i=0; i<Joints.size(); ++i)
{
for (u32 j=0; j<Joints[i].VertexIds.size(); ++j)
{
Joints[i].AbsoluteTransformation.inverseTranslateVect(
Vertices[Joints[i].VertexIds[j]].Pos);
Joints[i].AbsoluteTransformation.inverseRotateVect(
Vertices[Joints[i].VertexIds[j]].Pos);
Joints[i].AbsoluteTransformation.inverseRotateVect(
Vertices[Joints[i].VertexIds[j]].Normal);
}
}
AnimatedVertices = Vertices;
*/
delete [] buffer;
// clear arrays
Groups.clear();
return true;
}
core::stringc CMS3DMeshFileLoader::stripPathFromString(core::stringc string, bool returnPath)
{
s32 slashIndex=string.findLast('/'); // forward slash
s32 backSlash=string.findLast('\\'); // back slash
if (backSlash>slashIndex) slashIndex=backSlash;
if (slashIndex==-1)//no slashes found
if (returnPath)
return core::stringc(); //no path to return
else
return string;
if (returnPath)
return string.subString(0, slashIndex + 1);
else
return string.subString(slashIndex+1, string.size() - (slashIndex+1));
}
} // end namespace scene
} // end namespace irr
#endif

View File

@ -0,0 +1,59 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_MS3D_MESH_FILE_LOADER_H_INCLUDED__
#define __C_MS3D_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "IVideoDriver.h"
#include "CSkinnedMesh.h"
namespace irr
{
namespace scene
{
//! Meshloader capable of loading Milkshape 3D files
class CMS3DMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CMS3DMeshFileLoader(video::IVideoDriver* driver);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const c8* fileName);
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
virtual IAnimatedMesh* createMesh(irr::io::IReadFile* file);
private:
core::stringc stripPathFromString(core::stringc string, bool returnPath);
bool load(irr::io::IReadFile* file);
video::IVideoDriver* Driver;
CSkinnedMesh* AnimatedMesh;
struct SGroup
{
core::stringc Name;
core::array<u16> VertexIds;
u16 MaterialIdx;
};
core::array<SGroup> Groups;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -8,6 +8,9 @@
// This tool created by ZDimitor everyone can use it as wants
//--------------------------------------------------------------------------------
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
#include "CMY3DMeshFileLoader.h"
#include "SAnimatedMesh.h"
@ -837,3 +840,5 @@ core::array<ISceneNode*>& CMY3DMeshFileLoader::getChildNodes()
} // end namespace scnene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_MY3D_LOADER_

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
#include "COBJMeshFileLoader.h"
#include "SMeshBuffer.h"
#include "SAnimatedMesh.h"
@ -762,3 +765,5 @@ void COBJMeshFileLoader::cleanUp()
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OBJ_LOADER_

View File

@ -9,6 +9,9 @@
//
// See the header file for additional information including use and distribution rights.
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
#include "COCTLoader.h"
#include "ISceneManager.h"
#include "os.h"
@ -382,3 +385,5 @@ bool COCTLoader::isALoadableFileExtension(const c8* filename)
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OCT_LOADER_

View File

@ -3,6 +3,9 @@
// For conditions of distribution and use, see copyright notice in irrlicht.h
// orginally written by Christian Stehno, modified by Nikolaus Gebhardt
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
#include "COgreMeshFileLoader.h"
#include "os.h"
#include "SMeshBuffer.h"
@ -1028,3 +1031,4 @@ void COgreMeshFileLoader::clearMeshes()
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OGRE_LOADER_

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
#include "CQ3LevelMesh.h"
#include "ISceneManager.h"
#include "os.h"
@ -24,7 +27,7 @@ CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, video::IVideoDriver* driver, sce
{
#ifdef _DEBUG
IUnknown::setDebugName("CQ3LevelMesh");
#endif
#endif
s32 i;
for ( i = 0; i!= quake3::E_Q3_MESH_SIZE; ++i )
@ -53,7 +56,7 @@ CQ3LevelMesh::~CQ3LevelMesh()
if (LightMaps)
delete [] LightMaps;
if (Vertices)
delete [] Vertices;
@ -71,7 +74,7 @@ CQ3LevelMesh::~CQ3LevelMesh()
if (LeafFaces)
delete [] LeafFaces;
if (MeshVerts)
delete [] MeshVerts;
@ -461,7 +464,7 @@ void CQ3LevelMesh::parser_nextToken ()
}
// take /[name] as valid token..?!?!?. mhmm, maybe
break;
case '\n':
Parser.tokenresult = Q3_TOKEN_EOL;
return;
@ -889,14 +892,14 @@ void CQ3LevelMesh::constructMesh2()
} // end switch
}
}
}
//! constructs a mesh from the quake 3 level file.
void CQ3LevelMesh::constructMesh()
{
// reserve buffer.
// reserve buffer.
s32 i; // new ISO for scoping problem with some compilers
for (i=0; i<(NumTextures+1) * (NumLightMaps+1); ++i)
@ -938,9 +941,9 @@ void CQ3LevelMesh::constructMesh()
s32 idx = meshBuffer->getVertexCount();
s32 vidxes[3];
vidxes[0] = MeshVerts[Faces[i].meshVertIndex + tf +0]
vidxes[0] = MeshVerts[Faces[i].meshVertIndex + tf +0]
+ Faces[i].vertexIndex;
vidxes[1] = MeshVerts[Faces[i].meshVertIndex + tf +1]
vidxes[1] = MeshVerts[Faces[i].meshVertIndex + tf +1]
+ Faces[i].vertexIndex;
vidxes[2] = MeshVerts[Faces[i].meshVertIndex + tf +2]
+ Faces[i].vertexIndex;
@ -970,7 +973,7 @@ void CQ3LevelMesh::constructMesh()
break;
} // end switch
}
}
// helper method for creating curved surfaces, sent in by Dean P. Macri.
@ -1257,7 +1260,7 @@ void CQ3LevelMesh::createCurvedSurface2 ( SMeshBufferLightMap* meshBuffer,
if ( !v.equals ( m, tolerance ) )
continue;
meshBuffer->Vertices[k].Pos = v;
meshBuffer->Vertices[k].Pos = v;
//Bezier.Patch->Vertices[j].Pos = m;
}
}
@ -1450,7 +1453,7 @@ const quake3::SShader * CQ3LevelMesh::getShader ( const c8 * filename, s32 fileN
search.name = filename;
s32 index;
//! is Shader already in cache?
index = Shader.linear_search ( search );
if ( index >= 0 )
@ -1632,7 +1635,7 @@ void CQ3LevelMesh::loadTextures()
tex.set_used(NumTextures+1);
tex[0] = 0;
s32 t;// new ISO for scoping problem with some compilers
for (t=1; t<(NumTextures+1); ++t)
@ -1676,7 +1679,7 @@ void CQ3LevelMesh::loadTextures()
// lightmap is a CTexture::R8G8B8 format
lmapImg = Driver->createImageFromData(
video::ECF_R8G8B8,
video::ECF_R8G8B8,
lmapsize,
LightMaps[t-1].imageBits, true, false );
@ -1722,7 +1725,7 @@ void CQ3LevelMesh::cleanMeshes ()
{
// delete Meshbuffer
Mesh[g]->MeshBuffers[i]->drop();
Mesh[g]->MeshBuffers.erase(i);
Mesh[g]->MeshBuffers.erase(i);
}
else
++i;
@ -1751,7 +1754,7 @@ void CQ3LevelMesh::calcBoundingBoxes ()
//! loads a texture
video::ITexture* CQ3LevelMesh::loadTexture ( const tStringList &stringList )
{
static const char * extension[2] =
static const char * extension[2] =
{
".jpg",
".tga"
@ -1797,7 +1800,7 @@ void CQ3LevelMesh::loadTextures2()
// lightmap is a CTexture::R8G8B8 format
lmapImg = Driver->createImageFromData(
video::ECF_R8G8B8,
video::ECF_R8G8B8,
lmapsize,
LightMaps[t].imageBits, true, false );
@ -1808,7 +1811,7 @@ void CQ3LevelMesh::loadTextures2()
// load textures
Tex.set_used( NumTextures+1 );
const quake3::SShader * shader;
core::stringc list;
@ -1869,6 +1872,11 @@ const core::aabbox3d<f32>& CQ3LevelMesh::getBoundingBox() const
return Mesh[0]->getBoundingBox();
}
void CQ3LevelMesh::setBoundingBox( const core::aabbox3df& box)
{
return Mesh[0]->setBoundingBox(box); //?
}
//! Returns the type of the animated mesh.
E_ANIMATED_MESH_TYPE CQ3LevelMesh::getMeshType() const
@ -1879,3 +1887,4 @@ E_ANIMATED_MESH_TYPE CQ3LevelMesh::getMeshType() const
} // end namespace scene
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BSP_LOADER_

View File

@ -44,6 +44,9 @@ namespace scene
//! \return A bounding box of this mesh is returned.
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual void setBoundingBox( const core::aabbox3df& box);
//! Returns the type of the animated mesh.
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
@ -57,6 +60,40 @@ namespace scene
//! get's an interface to the entities
virtual const quake3::tQ3EntityList & getEntityList ();
//Link to held meshes? ...
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const
{
return 0;
}
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const
{
return 0;
}
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const
{
return 0;
}
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{
return;
}
private:
//! constructs a mesh from the quake 3 level file.
@ -104,45 +141,45 @@ namespace scene
{
s32 offset;
s32 length;
};
};
struct tBSPHeader
{
s32 strID; // This should always be 'IBSP'
s32 version; // This should be 0x2e for Quake 3 files
};
};
struct tBSPVertex
{
f32 vPosition[3]; // (x, y, z) position.
f32 vPosition[3]; // (x, y, z) position.
f32 vTextureCoord[2]; // (u, v) texture coordinate
f32 vLightmapCoord[2]; // (u, v) lightmap coordinate
f32 vNormal[3]; // (x, y, z) normal vector
u8 color[4]; // RGBA color for the vertex
u8 color[4]; // RGBA color for the vertex
};
struct tBSPFace
{
s32 textureID; // The index into the texture array
s32 effect; // The index for the effects (or -1 = n/a)
s32 type; // 1=polygon, 2=patch, 3=mesh, 4=billboard
s32 vertexIndex; // The index into this face's first vertex
s32 numOfVerts; // The number of vertices for this face
s32 meshVertIndex; // The index into the first meshvertex
s32 numMeshVerts; // The number of mesh vertices
s32 lightmapID; // The texture index for the lightmap
s32 lMapCorner[2]; // The face's lightmap corner in the image
s32 lMapSize[2]; // The size of the lightmap section
f32 lMapPos[3]; // The 3D origin of lightmap.
f32 lMapBitsets[2][3]; // The 3D space for s and t unit vectors.
f32 vNormal[3]; // The face normal.
s32 size[2]; // The bezier patch dimensions.
s32 textureID; // The index into the texture array
s32 effect; // The index for the effects (or -1 = n/a)
s32 type; // 1=polygon, 2=patch, 3=mesh, 4=billboard
s32 vertexIndex; // The index into this face's first vertex
s32 numOfVerts; // The number of vertices for this face
s32 meshVertIndex; // The index into the first meshvertex
s32 numMeshVerts; // The number of mesh vertices
s32 lightmapID; // The texture index for the lightmap
s32 lMapCorner[2]; // The face's lightmap corner in the image
s32 lMapSize[2]; // The size of the lightmap section
f32 lMapPos[3]; // The 3D origin of lightmap.
f32 lMapBitsets[2][3]; // The 3D space for s and t unit vectors.
f32 vNormal[3]; // The face normal.
s32 size[2]; // The bezier patch dimensions.
};
struct tBSPTexture
{
c8 strName[64]; // The name of the texture w/o the extension
u32 flags; // The surface flags (unknown)
c8 strName[64]; // The name of the texture w/o the extension
u32 flags; // The surface flags (unknown)
u32 contents; // The content flags (unknown)
};
@ -153,29 +190,29 @@ namespace scene
struct tBSPNode
{
s32 plane; // The index into the planes array
s32 front; // The child index for the front node
s32 back; // The child index for the back node
s32 mins[3]; // The bounding box min position.
s32 maxs[3]; // The bounding box max position.
};
s32 plane; // The index into the planes array
s32 front; // The child index for the front node
s32 back; // The child index for the back node
s32 mins[3]; // The bounding box min position.
s32 maxs[3]; // The bounding box max position.
};
struct tBSPLeaf
{
s32 cluster; // The visibility cluster
s32 area; // The area portal
s32 mins[3]; // The bounding box min position
s32 maxs[3]; // The bounding box max position
s32 leafface; // The first index into the face array
s32 numOfLeafFaces; // The number of faces for this leaf
s32 leafBrush; // The first index for into the brushes
s32 numOfLeafBrushes; // The number of brushes for this leaf
};
s32 cluster; // The visibility cluster
s32 area; // The area portal
s32 mins[3]; // The bounding box min position
s32 maxs[3]; // The bounding box max position
s32 leafface; // The first index into the face array
s32 numOfLeafFaces; // The number of faces for this leaf
s32 leafBrush; // The first index for into the brushes
s32 numOfLeafBrushes; // The number of brushes for this leaf
};
struct tBSPPlane
{
f32 vNormal[3]; // Plane normal.
f32 d; // The plane distance from origin
f32 vNormal[3]; // Plane normal.
f32 d; // The plane distance from origin
};
struct tBSPVisData
@ -183,44 +220,44 @@ namespace scene
s32 numOfClusters; // The number of clusters
s32 bytesPerCluster; // Bytes (8 bits) in the cluster's bitset
c8 *pBitsets; // Array of bytes holding the cluster vis.
};
};
struct tBSPBrush
struct tBSPBrush
{
s32 brushSide; // The starting brush side for the brush
s32 brushSide; // The starting brush side for the brush
s32 numOfBrushSides; // Number of brush sides for the brush
s32 textureID; // The texture index for the brush
};
};
struct tBSPBrushSide
struct tBSPBrushSide
{
s32 plane; // The plane index
s32 textureID; // The texture index
};
};
struct tBSPModel
struct tBSPModel
{
f32 min[3]; // The min position for the bounding box
f32 max[3]; // The max position for the bounding box.
s32 faceIndex; // The first face index in the model
s32 numOfFaces; // The number of faces in the model
s32 brushIndex; // The first brush index in the model
f32 max[3]; // The max position for the bounding box.
s32 faceIndex; // The first face index in the model
s32 numOfFaces; // The number of faces in the model
s32 brushIndex; // The first brush index in the model
s32 numOfBrushes; // The number brushes for the model
};
};
struct tBSPShader
{
c8 strName[64]; // The name of the shader file
s32 brushIndex; // The brush index for this shader
c8 strName[64]; // The name of the shader file
s32 brushIndex; // The brush index for this shader
s32 unknown; // This is 99% of the time 5
};
};
struct tBSPLights
{
u8 ambient[3]; // This is the ambient color in RGB
u8 directional[3]; // This is the directional color in RGB
u8 direction[2]; // The direction of the light: [phi,theta]
};
u8 direction[2]; // The direction of the light: [phi,theta]
};
void loadTextures (tBSPLump* l, io::IReadFile* file); // Load the textures
void loadLightmaps (tBSPLump* l, io::IReadFile* file); // Load the lightmaps
@ -299,7 +336,7 @@ namespace scene
s32 Level;
core::array<S3DVertex2TCoords_64> column[3];
};
SBezier Bezier;
@ -331,7 +368,7 @@ namespace scene
s32 *LeafFaces;
s32 NumLeafFaces;
s32 *MeshVerts; // The vertex offsets for a mesh
s32 *MeshVerts; // The vertex offsets for a mesh
s32 NumMeshVerts;
tBSPBrush* Brushes;

View File

@ -2,6 +2,7 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CSceneManager.h"
#include "IVideoDriver.h"
#include "IFileSystem.h"
@ -17,18 +18,65 @@
#include "CGeometryCreator.h"
#include "CDefaultMeshFormatLoader.h"
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
#include "CBSPMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
#include "CMD2MeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
#include "CMS3DMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
#include "C3DSMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_X_LOADER_
#include "CXMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
#include "COCTLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
#include "CCSMLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
#include "CLMTSMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
#include "CMY3DMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
#include "CColladaFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
#include "CDMFLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
#include "COgreMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
#include "COBJMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
#include "CMD3MeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
#include "CB3DMeshFileLoader.h"
#endif
#include "CCubeSceneNode.h"
#include "CSphereSceneNode.h"
@ -116,22 +164,56 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
// create manipulator
MeshManipulator = new CMeshManipulator();
// add default format loader
// add file format loaders
MeshLoaderList.push_back(new CDefaultMeshFormatLoader(FileSystem, Driver, this));
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
MeshLoaderList.push_back(new CBSPMeshFileLoader(FileSystem, Driver, this));
#endif
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
MeshLoaderList.push_back(new CMD2MeshFileLoader());
#endif
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver));
#endif
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
MeshLoaderList.push_back(new C3DSMeshFileLoader(MeshManipulator,FileSystem, Driver));
MeshLoaderList.push_back(new CXMeshFileLoader(MeshManipulator, Driver));
#endif
#ifdef _IRR_COMPILE_WITH_X_LOADER_
MeshLoaderList.push_back(new CXMeshFileLoader(this));
#endif
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
MeshLoaderList.push_back(new COCTLoader(Driver));
#endif
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
MeshLoaderList.push_back(new CCSMLoader(this, FileSystem));
#endif
#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters));
#endif
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this));
#endif
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
MeshLoaderList.push_back(new CColladaFileLoader(Driver, this, FileSystem));
#endif
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
MeshLoaderList.push_back(new CDMFLoader(Driver, this));
#endif
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver));
#endif
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
MeshLoaderList.push_back(new COBJMeshFileLoader(FileSystem, Driver));
#endif
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
MeshLoaderList.push_back(new CMD3MeshFileLoader(FileSystem, Driver));
// factories
#endif
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
#endif
// factories
ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
registerSceneNodeFactory(factory);
factory->drop();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
// Copyright (C) 2002-2006 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
//New skinned mesh
#ifndef __C_SKINNED_MESH_H_INCLUDED__
#define __C_SKINNED_MESH_H_INCLUDED__
#include "S3DVertex.h"
#include "irrString.h"
#include "matrix4.h"
#include "SMeshBuffer.h"
#include <quaternion.h>
#include "ISkinnedMesh.h"
namespace irr
{
namespace scene
{
class IAnimatedMeshSceneNode;
class IBoneSceneNode;
class CSkinnedMesh: public ISkinnedMesh
{
public:
//! constructor
CSkinnedMesh();
//! destructor
virtual ~CSkinnedMesh();
//! returns the amount of frames. If the amount is 1, it is a static (=non animated) mesh.
virtual s32 getFrameCount();
//! returns the animated mesh based on a detail level (which is ignored)
virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1);
//! Animates this mesh's joints based on frame input
//! blend: {0-old position, 1-New position}
virtual void animateMesh(f32 frame, f32 blend);
//! Preforms a software skin on this mesh based of joint positions
virtual void skinMesh();
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const;
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const;
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const;
//! returns an axis aligned bounding box
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! set user axis aligned bounding box
virtual void setBoundingBox( const core::aabbox3df& box);
//! sets a flag of all contained materials to a new value
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue);
//! Returns the type of the animated mesh.
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
//! Gets joint count.
virtual s32 getJointCount() const;
//! Gets the name of a joint.
virtual const c8* getJointName(s32 number) const;
//! Gets a joint number from its name
virtual s32 getJointNumber(const c8* name) const;
//! uses animation from another mesh
virtual bool useAnimationFrom(ISkinnedMesh *mesh);
//! Update Normals when Animating
//! False= Don't (default)
//! True = Update normals, slower
virtual void updateNormalsWhenAnimating(bool on);
//! Sets Interpolation Mode
virtual void setInterpolationMode(E_INTERPOLATION_MODE mode);
//! Recovers the joints from the mesh
virtual void recoverJointsFromMesh(core::array<IBoneSceneNode*> &JointChildSceneNodes);
//! Tranfers the joint data to the mesh
virtual void tranferJointsToMesh(core::array<IBoneSceneNode*> &JointChildSceneNodes);
//! Creates an array of joints from this mesh
virtual void createJoints(core::array<IBoneSceneNode*> &JointChildSceneNodes, IAnimatedMeshSceneNode* AnimatedMeshSceneNode, ISceneManager* SceneManager);
virtual void convertMeshToTangents();
//Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_
//these functions will use the needed arrays, set vaules, etc to help the loaders
//! exposed for loaders to add mesh buffers
virtual core::array<SSkinMeshBuffer*> &getMeshBuffers();
//! alternative method for adding joints
virtual core::array<SJoint*> &getAllJoints();
//! loaders should call this after populating the mesh
virtual void finalize();
virtual SSkinMeshBuffer *createBuffer();
virtual SJoint *createJoint(SJoint *parent=0);
virtual SPositionKey *createPositionKey(SJoint *joint);
virtual SScaleKey *createScaleKey(SJoint *joint);
virtual SRotationKey *createRotationKey(SJoint *joint);
virtual SWeight *createWeight(SJoint *joint);
private:
void checkForAnimation();
void normalizeWeights();
void buildAll_LocalAnimatedMatrices(); //public?
void buildAll_GlobalAnimatedMatrices(SJoint *Joint=0, SJoint *ParentJoint=0);
void getFrameData(f32 frame,SJoint *Node,core::vector3df &position, s32 &positionHint, core::vector3df &scale, s32 &scaleHint, core::quaternion &rotation, s32 &rotationHint);
void CalculateGlobalMatrixes(SJoint *Joint,SJoint *ParentJoint);
void SkinJoint(SJoint *Joint, SJoint *ParentJoint);
void calculateTangents(core::vector3df& normal,
core::vector3df& tangent, core::vector3df& binormal,
core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3,
core::vector2df& tc1, core::vector2df& tc2, core::vector2df& tc3);
//void createSkelton_Helper(ISceneManager* SceneManager, core::array<IBoneSceneNode*> &JointChildSceneNodes, IAnimatedMeshSceneNode *AnimatedMeshSceneNode, ISceneNode* ParentNode, SJoint *ParentNode, SJoint *Node);
core::array<SSkinMeshBuffer*> *SkinningBuffers; //Meshbuffer to skin, default is to skin localBuffers
core::array<SSkinMeshBuffer*> LocalBuffers;
core::array<SJoint*> AllJoints;
core::array<SJoint*> RootJoints;
bool HasAnimation;
bool PreparedForSkinning;
f32 AnimationFrames;
f32 lastAnimatedFrame;
f32 lastSkinnedFrame;
bool BoneControlUsed;
bool AnimateNormals;
E_INTERPOLATION_MODE InterpolationMode;
core::aabbox3d<f32> BoundingBox;
core::array< core::array<bool> > Vertices_Moved;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -1,863 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CXAnimationPlayer.h"
#include "ISceneNode.h"
#include "IVideoDriver.h"
#include "os.h"
#include "SMeshBuffer.h"
#include "IMeshManipulator.h"
namespace irr
{
namespace scene
{
//! constructor
CXAnimationPlayer::CXAnimationPlayer(CXFileReader* reader,
video::IVideoDriver* driver,
IMeshManipulator* manip,
const c8* filename)
: Reader(reader), Driver(driver), AnimatedMesh(0),
FileName(filename), Manipulator(manip), IsAnimatedSkinnedMesh(false),
CurrentAnimationTime(-1.0f), LastAnimationTime(1.0f),
CurrentAnimationSet(0), DebugSkeletonCrossSize(1.0f)
{
OriginalMesh = new scene::SMesh();
if (!Reader)
return;
if (Driver)
Driver->grab();
if (Manipulator)
Manipulator->grab();
Reader->grab();
createAnimationData();
}
//! destructor
CXAnimationPlayer::~CXAnimationPlayer()
{
OriginalMesh->drop();
if (Reader)
Reader->drop();
if (Driver)
Driver->drop();
if (AnimatedMesh)
AnimatedMesh->drop();
if (Manipulator)
Manipulator->drop();
}
//! Gets the frame count of the animated mesh.
s32 CXAnimationPlayer::getFrameCount()
{
return IsAnimatedSkinnedMesh ? (s32)LastAnimationTime : 1;
}
//! Returns the IMesh interface for a frame.
IMesh* CXAnimationPlayer::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
{
if (!IsAnimatedSkinnedMesh)
return OriginalMesh;
if (CurrentAnimationTime != (f32)frame)
{
CurrentAnimationTime = (f32)frame;
animateSkeleton();
modifySkin();
updateBoundingBoxFromAnimation();
}
return AnimatedMesh;
}
//! Returns an axis aligned bounding box of the mesh.
const core::aabbox3d<f32>& CXAnimationPlayer::getBoundingBox() const
{
return Box;
}
//! Returns the type of the animated mesh.
E_ANIMATED_MESH_TYPE CXAnimationPlayer::getMeshType() const
{
return EAMT_X;
}
void CXAnimationPlayer::createAnimationData()
{
int i, iCnt;
// get joints from x-file
core::array<CXFileReader::SXFrame>& pgRootFrames = Reader->getRootFrames();
iCnt = pgRootFrames.size();
for( i = 0; i < iCnt; i++ )
{
createJointData(pgRootFrames[i], -1);
createMeshData();
if (IsAnimatedSkinnedMesh && AnimatedMesh)
{
animateSkeleton();
modifySkin();
updateBoundingBoxFromAnimation();
DebugSkeletonCrossSize = AnimatedMesh->getBoundingBox().getExtent().X / 20.0f;
}
else
DebugSkeletonCrossSize = OriginalMesh->getBoundingBox().getExtent().X / 20.0f;
}
}
void CXAnimationPlayer::createMeshData()
{
int i, iCnt;
core::array<CXFileReader::SXFrame>& pgRootFrames = Reader->getRootFrames();
iCnt = pgRootFrames.size();
for( i = 0; i < iCnt; i++ )
{
// create mesh
addFrameToMesh(pgRootFrames[i]);
// recalculate box
OriginalMesh->recalculateBoundingBox();
// store box (fix by jox, thnx)
Box = OriginalMesh->getBoundingBox();
// sort weights in joints
for (s32 j=0; j<(s32)Joints.size(); ++j)
Joints[j].Weights.sort();
// copy mesh
AnimatedMesh = Manipulator->createMeshCopy(OriginalMesh);
// create and link animation data
prepareAnimationData();
// first animation
animateSkeleton();
modifySkin();
}
}
void CXAnimationPlayer::addFrameToMesh(CXFileReader::SXFrame& frame)
{
// go through all meshes
for (u32 m=0; m<frame.Meshes.size(); ++m)
{
// create mesh buffer for every material
if (frame.Meshes[m].MaterialList.Materials.empty())
os::Printer::log("Mesh without material found in x file.", ELL_WARNING);
for (u32 mt=0; mt<frame.Meshes[m].MaterialList.Materials.size(); ++mt)
{
// create buffer
SMeshBuffer *buf = new SMeshBuffer();
OriginalMesh->addMeshBuffer(buf);
buf->drop();
// new weights buffer
Weights.push_back( core::array<SVertexWeight>() );
// create material
buf->Material = getMaterialFromXMaterial(
frame.Meshes[m].MaterialList.Materials[mt]);
// add all faces of this material
addFacesToBuffer(OriginalMesh->MeshBuffers.size()-1,
frame.Meshes[m], mt, frame);
buf->recalculateBoundingBox();
}
}
// add child frames
for (u32 c=0; c<frame.ChildFrames.size(); ++c)
addFrameToMesh(frame.ChildFrames[c]);
}
video::SMaterial CXAnimationPlayer::getMaterialFromXMaterial(const CXFileReader::SXMaterial& xmat)
{
video::SMaterial mat;
mat.EmissiveColor = xmat.Emissive.toSColor();
mat.DiffuseColor = xmat.FaceColor.toSColor();
mat.SpecularColor = xmat.Specular.toSColor();
mat.Shininess = xmat.Power;
if (xmat.TextureFileName.size() != 0)
{
// use name from .x file
mat.Textures[0] = Driver->getTexture(xmat.TextureFileName.c_str());
if (mat.Textures[0] == 0)
// use path from .x file with texture name
mat.Textures[0] = Driver->getTexture(getTextureFileName(xmat.TextureFileName).c_str());
}
return mat;
}
void CXAnimationPlayer::addFacesToBuffer(s32 meshbuffernr, CXFileReader::SXMesh& mesh, s32 matnr, const CXFileReader::SXFrame& frame)
{
scene::SMeshBuffer* buf = (SMeshBuffer*)OriginalMesh->MeshBuffers[meshbuffernr];
u32 tcnt = mesh.TextureCoords.size();
u32 ncnt = mesh.Normals.size();
u32 ccnt = mesh.VertexColors.size();
// precompute which joint belongs to which weight array
core::array< s32 > jointNumberWeightNumberMap;
for (u32 w=0; w<mesh.SkinWeights.size(); ++w)
{
s32 jnr = getJointNumberFromName(mesh.SkinWeights[w].TransformNodeName);
if (jnr == -1)
os::Printer::log("Unknown Joint referenced in x file",
mesh.SkinWeights[w].TransformNodeName.c_str(), ELL_WARNING);
else
{
Joints[jnr].MatrixOffset = mesh.SkinWeights[w].MatrixOffset;
IsAnimatedSkinnedMesh = true;
}
jointNumberWeightNumberMap.push_back(jnr);
}
video::S3DVertex v;
v.Color.set(255,255,255,255);
// add only those with material matnr
for (u32 i=0; i<mesh.MaterialList.FaceIndices.size(); ++i)
{
if (mesh.MaterialList.FaceIndices[i] == matnr)
{
// add face number i
for (s32 f=0; f<3; ++f)
{
s32 idxidx = i*3+f;
s32 idx = mesh.Indices[idxidx];
v.Pos = mesh.Vertices[idx];
if (tcnt) v.TCoords = mesh.TextureCoords[idx];
if (ncnt) v.Normal = mesh.Normals[mesh.NormalIndices[idxidx]];
if (ccnt)
v.Color = mesh.VertexColors[idx].Color.toSColor();
else
v.Color = buf->Material.DiffuseColor;
s32 nidx = buf->Vertices.linear_reverse_search(v);
bool alreadyIn = (nidx != -1);
if (!alreadyIn)
{
nidx = buf->Vertices.size();
buf->Indices.push_back(nidx);
buf->Vertices.push_back(v);
Weights[meshbuffernr].push_back(SVertexWeight());
}
else
buf->Indices.push_back(nidx);
bool isWeighted = alreadyIn;
// add weight data of this vertex to all joints
if (!alreadyIn)
for (s32 w=0; w<(s32)mesh.SkinWeights.size(); ++w)
{
s32 vertexinweights = mesh.SkinWeights[w].Weights.binary_search(CXFileReader::SXWeight(idx));
if (vertexinweights != -1)
{
s32 jnr = jointNumberWeightNumberMap[w];
if (jnr != -1)
{
// weight per joint
Joints[jnr].Weights.push_back(SWeightData(
meshbuffernr,
nidx,
mesh.SkinWeights[w].Weights[vertexinweights].Weight));
// weight per vertex
SVertexWeight& weight = Weights[meshbuffernr].pointer()[nidx];
weight.add(mesh.SkinWeights[w].Weights[vertexinweights].Weight, jnr);
isWeighted = true;
}
}
} // end for all weights
// if this vertex does not have a weight, create a virtual new
// joint and attach it to this one
if (!isWeighted)
addVirtualWeight(meshbuffernr, nidx, mesh, frame);
} // end for all faces
} // end for all materials
}
// generate missing normals
if (!ncnt)
{
// Using Mesh manipulator
Manipulator->recalculateNormals ( buf, true );
}
/*// transform vertices and normals
core::matrix4 mat = frame.LocalMatrix;
s32 vcnt = buf->Vertices.size();
for (s32 u=0; u<vcnt; ++u)
{
mat.transformVect(buf->Vertices[u].Pos);
mat.rotateVect(buf->Vertices[u].Normal);
}*/
}
void CXAnimationPlayer::addVirtualWeight(s32 meshbuffernr, s32 vtxidx, CXFileReader::SXMesh& mesh,
const CXFileReader::SXFrame& frame)
{
// find original joint of vertex
s32 jnr = getJointNumberFromName(frame.Name);
if (jnr == -1)
return;
// weight per joint
Joints[jnr].Weights.push_back(SWeightData(
meshbuffernr,
vtxidx,
1.0f));
// weight per vertex
SVertexWeight& weight = Weights[meshbuffernr].pointer()[vtxidx];
weight.add(1.0f, jnr);
}
s32 CXAnimationPlayer::getJointNumberFromName(const core::stringc& name) const
{
for (s32 i=0; i<(s32)Joints.size(); ++i)
if (Joints[i].Name == name)
return i;
return -1;
}
//! Use .x file path as prefix for texture
core::stringc CXAnimationPlayer::getTextureFileName(const core::stringc& texture)
{
s32 idx = -1;
idx = FileName.findLast('/');
if (idx == -1)
idx = FileName.findLast('\\');
if (idx == -1)
return texture;
return FileName.subString(0, idx+1)+texture;
}
void CXAnimationPlayer::createJointData(const CXFileReader::SXFrame& f, s32 JointParent)
{
// add joint
s32 index = Joints.size();
Joints.push_back(SJoint());
SJoint& j = Joints.getLast();
j.Parent = JointParent;
j.GlobalMatrix = f.GlobalMatrix;
j.LocalMatrix = f.LocalMatrix;
j.AnimatedMatrix = j.GlobalMatrix;
j.LocalAnimatedMatrix = j.LocalMatrix;
j.CombinedAnimationMatrix = j.AnimatedMatrix * j.MatrixOffset;
j.IsVirtualJoint = false;
j.Name = f.Name;
// add all children
for (s32 i=0; i<(s32)f.ChildFrames.size(); ++i)
createJointData(f.ChildFrames[i], index);
}
//! Returns a pointer to a transformation matrix
core::matrix4* CXAnimationPlayer::getMatrixOfJoint(s32 jointNumber, s32 frame)
{
if (jointNumber < 0 || jointNumber >= (s32)Joints.size())
return 0;
return &Joints[jointNumber].AnimatedMatrix;
}
//! Gets joint count.
s32 CXAnimationPlayer::getJointCount() const
{
return Joints.size();
}
//! Gets the name of a joint.
const c8* CXAnimationPlayer::getJointName(s32 number) const
{
if (number<0 || number>=(s32)Joints.size())
return 0;
return Joints[number].Name.c_str();
}
//! Gets a joint number from its name
s32 CXAnimationPlayer::getJointNumber(const c8* name) const
{
for (s32 i=0; i<(s32)Joints.size(); ++i)
if (Joints[i].Name == name)
return i;
return -1;
}
//! Returns a pointer to list of points containing the skeleton.
const core::array<core::vector3df>* CXAnimationPlayer::getDrawableSkeleton(s32 frame)
{
DebugSkeleton.clear();
f32 k = DebugSkeletonCrossSize;
f32 p = 0.0f;
for (s32 i=0; i<(s32)Joints.size(); ++i)
{
core::vector3df start(p,p,p);
core::vector3df end(p,p,p);
Joints[i].AnimatedMatrix.transformVect(start);
DebugSkeleton.push_back(start);
DebugSkeleton.push_back(start + core::vector3df(0,k,0));
DebugSkeleton.push_back(start);
DebugSkeleton.push_back(start + core::vector3df(0,-k,0));
DebugSkeleton.push_back(start);
DebugSkeleton.push_back(start + core::vector3df(k,0,0));
DebugSkeleton.push_back(start);
DebugSkeleton.push_back(start + core::vector3df(-k,0,0));
DebugSkeleton.push_back(start);
DebugSkeleton.push_back(start + core::vector3df(0,0,k));
DebugSkeleton.push_back(start);
DebugSkeleton.push_back(start + core::vector3df(0,0,-k));
if (Joints[i].Parent != -1)
{
Joints[Joints[i].Parent].AnimatedMatrix.transformVect(end);
DebugSkeleton.push_back(end);
DebugSkeleton.push_back(start);
}
}
return &DebugSkeleton;
}
//! animates the skeleton based on the animation data
void CXAnimationPlayer::animateSkeleton()
{
if (!AnimationSets.empty())
{
// reset joints
for (u32 jii=0; jii<Joints.size(); ++jii)
{
Joints[jii].LocalAnimatedMatrix.makeIdentity();
Joints[jii].WasAnimatedThisFrame = false;
}
const SXAnimationSet& currentSet = AnimationSets[CurrentAnimationSet];
// go through all animation tracks
for (u32 i=0; i<currentSet.Animations.size(); ++i)
{
SJoint& joint = Joints[currentSet.Animations[i].jointNr];
// find indices to interpolate between
s32 idx1 = -1;
s32 idx2 = -1;
for (s32 t=0; t<(s32)currentSet.Animations[i].Times.size()-1; ++t)
{
if (currentSet.Animations[i].Times[t] <= CurrentAnimationTime &&
currentSet.Animations[i].Times[t+1] >= CurrentAnimationTime)
{
idx1 = t;
idx2 = (t+1) % currentSet.Animations[i].Times.size();
break;
}
}
if (idx1 == -1)
continue;
// calculate interpolation factor
f32 factor = (CurrentAnimationTime - currentSet.Animations[i].Times[idx1]) /
(currentSet.Animations[i].Times[idx2] - currentSet.Animations[i].Times[idx1]);
// animate it
switch(currentSet.Animations[i].keyType)
{
case 0: // rotation
{
// with this code, rotations are not 100% ok, they are
// mirrored.
core::quaternion q;
q.slerp(currentSet.Animations[i].Quaternions[idx1],
currentSet.Animations[i].Quaternions[idx2],
factor);
joint.LocalAnimatedMatrix *= q.getMatrix();
joint.WasAnimatedThisFrame = true;
}
break;
case 1: // scale
{
core::matrix4 mat1, mat2;
mat1.setScale(currentSet.Animations[i].Vectors[idx1]);
mat2.setScale(currentSet.Animations[i].Vectors[idx2]);
joint.LocalAnimatedMatrix *= mat1.interpolate(mat2, factor);
joint.WasAnimatedThisFrame = true;
}
break;
case 2: // position
{
core::matrix4 mat1, mat2;
mat1.setTranslation(currentSet.Animations[i].Vectors[idx1]);
mat2.setTranslation(currentSet.Animations[i].Vectors[idx2]);
joint.LocalAnimatedMatrix *= mat1.interpolate(mat2, factor);
joint.WasAnimatedThisFrame = true;
}
break;
case 4:
case 3: // matrix
{
joint.LocalAnimatedMatrix =
currentSet.Animations[i].Matrices[idx1].interpolate(
currentSet.Animations[i].Matrices[idx2], factor);
joint.WasAnimatedThisFrame = true;
}
break;
}
}
}
// update all joints
for (s32 ji=0; ji<(s32)Joints.size(); ++ji)
{
if (!Joints[ji].WasAnimatedThisFrame)
Joints[ji].LocalAnimatedMatrix = Joints[ji].LocalMatrix;
Joints[ji].AnimatedMatrix = Joints[ji].LocalAnimatedMatrix;
if (Joints[ji].Parent != -1)
Joints[ji].AnimatedMatrix = Joints[Joints[ji].Parent].AnimatedMatrix * Joints[ji].AnimatedMatrix;
Joints[ji].CombinedAnimationMatrix = Joints[ji].AnimatedMatrix *
Joints[ji].MatrixOffset;
}
}
//! modifies the skin based on the animated skeleton
void CXAnimationPlayer::modifySkin()
{
// set animated vertices to zero
for (s32 k=0; k<(s32)Joints.size(); ++k)
{
for (s32 w=0; w<(s32)Joints[k].Weights.size(); ++w)
{
SWeightData& wd = Joints[k].Weights[w];
#ifdef _XREADER_DEBUG
if (wd.buffer >= AnimatedMesh->getMeshBufferCount() ||
wd.vertex >= AnimatedMesh->getMeshBuffer(wd.buffer)->getVertexCount())
os::Printer::log("CXAnimationPlayer: Invalid Weights");
#endif
video::S3DVertex* nv = (video::S3DVertex*)AnimatedMesh->getMeshBuffer(wd.buffer)->getVertices();
nv[wd.vertex].Pos.set(0,0,0);
}
}
#ifdef _XREADER_DEBUG
bool somethingIsWrong = false;
// check if all vertices are set to zero
for (u32 mb=0; mb<AnimatedMesh->getMeshBufferCount(); ++mb)
{
video::S3DVertex* v = (video::S3DVertex*)AnimatedMesh->getMeshBuffer(mb)->getVertices();
s32 c = AnimatedMesh->getMeshBuffer(mb)->getVertexCount();
for (s32 vt=0; vt<c; ++vt)
if (v[vt].Pos != core::vector3df(0,0,0))
{
char tmp[255];
sprintf(tmp, "CXAnimationPlayer: Vertex not null. Buf:%d Vtx:%d", mb, vt);
// this can happen if something is wrong with the vertex weights,
// not all vertices have a weight attached.
os::Printer::log(tmp);
somethingIsWrong = true;
}
}
if (somethingIsWrong)
{
// write out mesh informations
char tmp[255];
sprintf(tmp, "CXAnimationPlayer: Meshbuffers:%d", AnimatedMesh->getMeshBufferCount());
os::Printer::log(tmp);
for (u32 mb=0; mb<AnimatedMesh->getMeshBufferCount(); ++mb)
{
sprintf(tmp, "CXAnimationPlayer: Meshbuffer #%d: %d vertices", mb, AnimatedMesh->getMeshBuffer(mb)->getVertexCount());
os::Printer::log(tmp);
}
}
#endif
// transform vertices
for (u32 mb=0; mb<AnimatedMesh->getMeshBufferCount(); ++mb)
{
video::S3DVertex* av = (video::S3DVertex*)AnimatedMesh->getMeshBuffer(mb)->getVertices();
video::S3DVertex* ov = (video::S3DVertex*)OriginalMesh->getMeshBuffer(mb)->getVertices();
const u32 c = AnimatedMesh->getMeshBuffer(mb)->getVertexCount();
for (u32 vt=0; vt<c; ++vt)
{
core::vector3df vtmp;
core::vector3df orig = ov[vt].Pos;
const SVertexWeight& weight = Weights[mb].pointer()[vt];
av[vt].Pos.set(0.0f,0.0f,0.0f);
s32 w;
for (w=0; w<weight.weightCount; ++w)
{
Joints[weight.joint[w]].CombinedAnimationMatrix.transformVect(
vtmp, orig);
vtmp *= weight.weight[w];
av[vt].Pos += vtmp;
}
// yin nadie: let's modify the normals
orig += ov[vt].Normal;
av[vt].Normal.set(0.0f,0.0f,0.0f);
for( w = 0; w < weight.weightCount; ++w )
{
Joints[weight.joint[w]].CombinedAnimationMatrix.transformVect( vtmp,orig );
vtmp *= weight.weight[w];
av[vt].Normal += vtmp;
}
av[vt].Normal -= av[ vt ].Pos;
av[vt].Normal.normalize();
// yin nadie: normals modified
}
}
}
//! prepares animation data which was read in from the .x file
void CXAnimationPlayer::prepareAnimationData()
{
s32 animationSetCount = Reader->getAnimationSetCount();
for (s32 i=0; i<animationSetCount; ++i)
{
AnimationSets.push_back(SXAnimationSet());
SXAnimationSet& mySet = AnimationSets.getLast();
const CXFileReader::SXAnimationSet& readerSet = Reader->getAnimationSet(i);
mySet.AnimationName = readerSet.AnimationName;
// through all animations
for (s32 a=0; a<(s32)readerSet.Animations.size(); ++a)
{
// through all keys
for (s32 k=0; k<(s32)readerSet.Animations[a].Keys.size(); ++k)
{
// link with joint
s32 jntnr = getJointNumberFromName(readerSet.Animations[a].FrameName);
if (jntnr == -1)
{
os::Printer::log(
"CXAnimationPlayer: Animationtrack without corresponding joint found",
readerSet.Animations[a].FrameName.c_str());
continue;
}
// copy track
s32 keyCount = (s32)readerSet.Animations[a].Keys[k].numberOfKeys;
if (!keyCount)
{
os::Printer::log(
"CXAnimationPlayer: Skipping Animationtrack with zero key frames",
readerSet.Animations[a].FrameName.c_str());
continue;
}
// add new track
mySet.Animations.push_back(SXAnimationTrack());
SXAnimationTrack& myTrack = mySet.Animations.getLast();
myTrack.jointNr = jntnr;
IsAnimatedSkinnedMesh = true;
s32 type = readerSet.Animations[a].Keys[k].keyType;
s32 l;
myTrack.keyType = type;
#ifdef _XREADER_DEBUG
char tmp[255];
sprintf(tmp, "adding track %s with %d keys, type:%d", readerSet.Animations[a].FrameName.c_str(), keyCount, type);
os::Printer::log(tmp);
#endif
switch(type)
{
case 0: // quaternion
for (l=0; l<keyCount; ++l)
myTrack.Quaternions.push_back(readerSet.Animations[a].Keys[k].getQuaternion(l));
break;
case 1: // scale
case 2: // position
for (l=0; l<keyCount; ++l)
myTrack.Vectors.push_back(readerSet.Animations[a].Keys[k].getVector(l));
break;
case 4:
case 3: // matrix
for (l=0; l<keyCount; ++l)
myTrack.Matrices.push_back(readerSet.Animations[a].Keys[k].getMatrix(l));
break;
}
// copy times
if (keyCount)
{
for (l=0; l<keyCount; ++l)
myTrack.Times.push_back((f32)readerSet.Animations[a].Keys[k].time[l]);
if (myTrack.Times.getLast() > LastAnimationTime)
LastAnimationTime = myTrack.Times.getLast();
}
}
}
// sort animation tracks
mySet.Animations.sort();
}
}
void CXAnimationPlayer::updateBoundingBoxFromAnimation()
{
if (!Joints.size())
return;
bool first = true;
for (u32 i=0; i<Joints.size(); ++i)
// I think there should be two vectors from aabbox of each joint should
// be used instead of just (0,0,0)
// if (!Joints[i].Weights.empty())
{
core::vector3df p(0,0,0);
Joints[i].AnimatedMatrix.transformVect(p);
if (first)
Box.reset(p);
else
Box.addInternalPoint(p);
first = false;
}
AnimatedMesh->BoundingBox = Box;
}
//! Returns amount of animations in .X-file.
s32 CXAnimationPlayer::getAnimationCount() const
{
return AnimationSets.size();
}
//! Returns the name of an animation.
const c8* CXAnimationPlayer::getAnimationName(s32 idx) const
{
if (idx < 0 || idx >= (s32)AnimationSets.size())
return 0;
return AnimationSets[idx].AnimationName.c_str();
}
//! Sets an animation as animation to play back.
void CXAnimationPlayer::setCurrentAnimation(s32 idx)
{
if (idx < 0 || idx >= (s32)AnimationSets.size())
return;
CurrentAnimationSet = idx;
}
//! Sets an animation as animation to play back.
bool CXAnimationPlayer::setCurrentAnimation(const c8* name)
{
for (s32 i=0; i<(s32)AnimationSets.size(); ++i)
if (AnimationSets[i].AnimationName == name)
{
CurrentAnimationSet = i;
return true;
}
return false;
}
} // end namespace scene
} // end namespace irr

View File

@ -1,219 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_X_ANIMATION_PLAYER_H_INCLUDED__
#define __C_X_ANIMATION_PLAYER_H_INCLUDED__
#include "IAnimatedMeshX.h"
#include "CXFileReader.h"
#include "SMesh.h"
#include "SMeshBuffer.h"
namespace irr
{
namespace video
{
class IVideoDriver;
}
namespace scene
{
class IMeshManipulator;
class CXAnimationPlayer : public IAnimatedMeshX
{
public:
//! constructor
CXAnimationPlayer(CXFileReader* reader,
video::IVideoDriver* driver,
IMeshManipulator* manip,
const c8* filename);
//! destructor
virtual ~CXAnimationPlayer();
//! Gets the frame count of the animated mesh.
virtual s32 getFrameCount();
//! Returns the IMesh interface for a frame.
virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1);
//! Returns an axis aligned bounding box of the mesh.
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! Returns the type of the animated mesh.
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
//! Returns a pointer to a transformation matrix
virtual core::matrix4* getMatrixOfJoint(s32 jointNumber, s32 frame);
//! Gets joint count.
virtual s32 getJointCount() const;
//! Gets the name of a joint.
virtual const c8* getJointName(s32 number) const;
//! Gets a joint number from its name
virtual s32 getJointNumber(const c8* name) const;
//! Returns a pointer to list of points containing the skeleton.
virtual const core::array<core::vector3df>* getDrawableSkeleton(s32 frame);
//! Returns amount of animations in .X-file.
virtual s32 getAnimationCount() const;
//! Returns the name of an animation.
virtual const c8* getAnimationName(s32 idx) const;
//! Sets an animation as animation to play back.
virtual void setCurrentAnimation(s32 idx);
//! Sets an animation as animation to play back.
virtual bool setCurrentAnimation(const c8* name);
private:
struct SWeightData
{
SWeightData() {};
SWeightData(const SWeightData& other)
: buffer(other.buffer), vertex(other.vertex), weight(other.weight)
{}
SWeightData(s32 b, s32 v, f32 w)
: buffer(b), vertex(v), weight(w)
{}
s32 buffer;
s32 vertex;
f32 weight;
bool operator <(const SWeightData& other) const
{
return (buffer < other.buffer ||
(buffer == other.buffer &&
vertex < other.vertex) ||
(buffer == other.buffer &&
vertex == other.vertex &&
weight < other.weight));
}
};
struct SVertexWeight
{
SVertexWeight() : weightCount(0) {}
// weight per vertex, at maximum, 4 joints per vertex
f32 weight[4];
s32 joint[4];
s32 weightCount;
void add(f32 _weight, s32 _joint)
{
if (weightCount == 4)
return;
weight[weightCount] = _weight;
joint[weightCount] = _joint;
++weightCount;
}
};
struct SJoint
{
s32 Parent; // index of parent
core::array<SWeightData> Weights;
core::matrix4 MatrixOffset;
core::matrix4 LocalMatrix;
core::matrix4 GlobalMatrix;
core::matrix4 AnimatedMatrix;
core::matrix4 LocalAnimatedMatrix;
core::matrix4 CombinedAnimationMatrix; // for faster computing
core::stringc Name;
bool IsVirtualJoint; // for in .x file not weighted vertices
bool WasAnimatedThisFrame; // used by animateSkeleton()
};
void createAnimationData();
void createJointData(const CXFileReader::SXFrame& f, s32 JointParent);
void createMeshData();
void addFrameToMesh(CXFileReader::SXFrame& frame);
video::SMaterial getMaterialFromXMaterial(const CXFileReader::SXMaterial& xmat);
void addFacesToBuffer(s32 meshbuffernr, CXFileReader::SXMesh& mesh, s32 matnr, const CXFileReader::SXFrame& frame);
//! use .x file path as prefix for texture
core::stringc getTextureFileName(const core::stringc& texture);
s32 getJointNumberFromName(const core::stringc& name) const;
//! prepares animation data which was read in from the .x file
void prepareAnimationData();
//! animates the skeleton based on the animation data
void animateSkeleton();
//! modifies the skin based on the animated skeleton
void modifySkin();
void updateBoundingBoxFromAnimation();
void addVirtualWeight(s32 meshbuffernr, s32 vtxidx, CXFileReader::SXMesh& mesh,
const CXFileReader::SXFrame& frame);
CXFileReader* Reader;
video::IVideoDriver* Driver;
scene::SMesh *OriginalMesh;
scene::SMesh *AnimatedMesh;
core::aabbox3df Box;
core::stringc FileName;
IMeshManipulator* Manipulator;
core::array<core::vector3df> DebugSkeleton;
bool IsAnimatedSkinnedMesh;
core::array<SJoint> Joints;
f32 CurrentAnimationTime;
f32 LastAnimationTime;
s32 CurrentAnimationSet;
f32 DebugSkeletonCrossSize;
// one array of weights per mesh buffer
core::array< core::array<SVertexWeight> > Weights;
// data for animations
struct SXAnimationTrack
{
s32 jointNr;
s32 keyType; // 0=rotation, 1=scale, 2=position, 3=matrix
core::array<core::quaternion> Quaternions;
core::array<core::vector3df> Vectors;
core::array<core::matrix4> Matrices;
core::array<f32> Times;
bool operator <(SXAnimationTrack& other) const
{
if (jointNr != other.jointNr)
return (jointNr < other.jointNr);
return keyType > other.keyType;
}
};
struct SXAnimationSet
{
core::stringc AnimationName;
core::array<SXAnimationTrack> Animations;
};
core::array<SXAnimationSet> AnimationSets;
};
} // end namespace scene
} // end namespace irr
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,310 +0,0 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_X_FILE_READER_H_INCLUDED__
#define __C_X_FILE_READER_H_INCLUDED__
#include "IReadFile.h"
#include "irrString.h"
#include "matrix4.h"
#include "SColor.h"
#include "irrArray.h"
#include "vector2d.h"
#include "quaternion.h"
//#define _XREADER_DEBUG
namespace irr
{
namespace scene
{
//! This is a .x file reader. It only reads data from uncompressed .x files.
class CXFileReader : public virtual IUnknown
{
public:
struct SXAnimationSet;
struct SXFrame;
CXFileReader(io::IReadFile* file);
~CXFileReader();
//! Returns an error occured during reading the file
bool errorHappened() const;
//! Returns if the loaded mesh is static
bool isStaticMesh() const;
//! returns count of animations
s32 getAnimationSetCount() const;
//! returns a specific animation set
SXAnimationSet& getAnimationSet(s32 i);
//! returns array of root frames
core::array<SXFrame> & getRootFrames();
struct SXMaterial
{
video::SColorf FaceColor; // note: RGBA
f32 Power;
video::SColorf Specular; // RGB
video::SColorf Emissive; // RGB
core::stringc TextureFileName;
};
struct SXMeshMaterialList
{
core::array<s32> FaceIndices; // index of material for each face
core::array<SXMaterial> Materials; // material array
};
struct SXTemplateMaterial
{
core::stringc Name; // template name from Xfile
SXMaterial Material; // material
};
struct SXIndexedColor
{
s32 Index;
video::SColorf Color;
};
struct SXSkinMeshHeader
{
s32 MaxSkinWeightsPerVertex; // Maximum number of transforms that affect a vertex in the mesh.
s32 MaxSkinWeightsPerFace; // Maximum number of unique transforms that affect the three vertices of any face.
s32 BoneCount; // Number of bones that affect vertices in this mesh.
};
struct SXWeight
{
SXWeight() {};
SXWeight(s32 vtidx): VertexIndex(vtidx) {}
s32 VertexIndex;
f32 Weight;
bool operator <(const SXWeight& other) const
{
return VertexIndex < other.VertexIndex;
}
};
struct SXSkinWeight
{
core::stringc TransformNodeName; // name of the bone
core::array< SXWeight > Weights;
core::matrix4 MatrixOffset; // transforms the mesh vertices to the space of the bone
// When concatenated to the bone's transform, this provides the
// world space coordinates of the mesh as affected by the bone
};
struct SXMesh
{
// this mesh contains triangulated texture data.
// because in an .x file, faces can be made of more than 3
// vertices, the indices data structure is triangulated during the
// loading process. The IndexCountPerFace array is filled during
// this triangulation process and stores how much indices belong to
// every face. This data structure can be ignored, because all data
// in this structure is triangulated.
core::stringc Name;
core::array<core::vector3df> Vertices;
core::array< s32 > Indices; // triangle indices
// optional:
core::array<core::vector2df> TextureCoords;
core::array<core::vector3df> Normals;
core::array<s32> NormalIndices; // amount is equal to Indices amount
core::array< s32 > IndexCountPerFace; // default 3, but could be more
core::array< SXIndexedColor > VertexColors;
core::array< SXSkinWeight > SkinWeights;
SXMeshMaterialList MaterialList;
SXSkinMeshHeader SkinMeshHeader;
};
struct SXFrame
{
SXFrame() : iLevel(0), pParent(0) { }
int iLevel;
SXFrame * pParent;
core::stringc Name;
core::matrix4 LocalMatrix;
core::matrix4 GlobalMatrix;
core::array<SXMesh> Meshes;
core::array<SXFrame> ChildFrames;
};
struct SXAnimationKey
{
SXAnimationKey() : keyType(-1), numberOfKeys(0), time(0), data(0) { }
void del()
{
delete [] time;
switch(keyType)
{
case -1: break;
case 0 : delete [] (core::quaternion*)data; break;
case 1 :
case 2 : delete [] (core::vector3df*)data; break;
case 3 :
case 4 : delete [] (core::matrix4*)data; break;
}
}
void init()
{
time = new s32[numberOfKeys];
switch(keyType)
{
case 0 : data = new core::quaternion[numberOfKeys]; break;
case 1 :
case 2 : data = new core::vector3df[numberOfKeys]; break;
case 3 :
case 4 : data = new core::matrix4[numberOfKeys]; break;
}
}
core::matrix4& getMatrix(s32 nr) const
{
return ((core::matrix4*)data)[nr];
}
core::vector3df& getVector(s32 nr) const
{
return ((core::vector3df*)data)[nr];
}
core::quaternion& getQuaternion(s32 nr) const
{
return ((core::quaternion*)data)[nr];
}
s32 keyType; // 0=rotation, 1=scale, 2=position, 3=matrix
s32 numberOfKeys;
s32* time;
void* data;
};
struct SXAnimation
{
core::stringc FrameName;
core::array<SXAnimationKey> Keys;
// optional, from AnimationOptions:
bool closed; // default true
bool linearPositionQuality; // if false: spline position quality
};
struct SXAnimationSet
{
core::stringc AnimationName;
core::array<SXAnimation> Animations;
};
private:
//! Parses the file
bool parseFile();
//! Reads file into memory
bool readFileIntoMemory(io::IReadFile* file);
//! Parses the next Data object in the file
bool parseDataObject();
//! places pointer to next begin of a token, and ignores comments
void findNextNoneWhiteSpace();
//! places pointer to next begin of a token, which must be a number,
// and ignores comments
void findNextNoneWhiteSpaceNumber();
//! returns next parseable token. Returns empty string if no token there
core::stringc getNextToken();
//! reads header of dataobject including the opening brace.
//! returns false if error happened, and writes name of object
//! if there is one
bool readHeadOfDataObject(core::stringc* outname=0);
//! checks for two following semicolons, returns false if they are not there
bool checkForTwoFollowingSemicolons();
//! reads a x file style string
bool getNextTokenAsString(core::stringc& out);
inline u16 readBinWord();
inline u32 readBinDWord();
inline s32 readInt();
inline f32 readFloat();
inline bool readVector2(core::vector2df& vec);
inline bool readVector3(core::vector3df& vec);
inline bool readRGB(video::SColorf& color);
inline bool readRGBA(video::SColorf& color);
bool parseDataObjectTemplate();
bool parseDataObjectFrame(SXFrame &frame);
bool parseDataObjectTransformationMatrix(core::matrix4 &mat);
bool parseDataObjectMesh(SXMesh &mesh);
bool parseDataObjectMeshNormals(core::array<core::vector3df>& normals,
core::array< s32 >& normalIndices, s32 triangulatedIndexCount,
core::array< s32 >& indexCountPerFace);
bool parseDataObjectMeshTextureCoords(core::array<core::vector2df>& textureCoords);
bool parseDataObjectMeshVertexColors(core::array<SXIndexedColor>& vertexColors);
bool parseDataObjectMeshMaterialList(SXMeshMaterialList& materiallist,
s32 triangulatedIndexCount, core::array< s32 >& indexCountPerFace);
bool parseDataObjectMaterial(SXMaterial& material);
bool parseDataObjectTextureFilename(core::stringc& texturename);
bool parseDataObjectSkinMeshHeader(SXSkinMeshHeader& header);
bool parseDataObjectSkinWeights(SXSkinWeight& weights);
bool parseDataObjectAnimationSet(SXAnimationSet& set);
bool parseDataObjectAnimation(SXAnimation& anim);
bool parseDataObjectAnimationKey(SXAnimationKey& animkey);
bool parseUnknownDataObject();
void readUntilEndOfLine();
void computeGlobalFrameMatrices(SXFrame& frame, const SXFrame* const parent);
void optimizeFrames( SXFrame * pgFrame, SXFrame * pgParent );
bool validateMesh(SXFrame* frame);
s32 MajorVersion;
s32 MinorVersion;
bool binary;
s32 binaryNumCount;
c8* Buffer;
s32 Size;
c8 FloatSize;
const c8* P;
c8* End;
bool ErrorHappened;
bool m_bFrameRemoved;
SXFrame * m_pgCurFrame;
core::array<SXFrame>RootFrames;
core::array<SXAnimationSet> AnimationSets;
core::array<SXTemplateMaterial> TemplateMaterials;
};
} // end namespace scene
} // end namespace irr
#endif

File diff suppressed because it is too large Load Diff

View File

@ -6,12 +6,13 @@
#define __C_X_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "IFileSystem.h"
#include "IReadFile.h"
#include "IVideoDriver.h"
#include "irrString.h"
#include "SMesh.h"
#include "CXFileReader.h"
#include "SMeshBuffer.h"
#include "CSkinnedMesh.h"
namespace irr
{
@ -25,7 +26,7 @@ class CXMeshFileLoader : public IMeshLoader
public:
//! Constructor
CXMeshFileLoader(IMeshManipulator* manip, video::IVideoDriver* driver);
CXMeshFileLoader(scene::ISceneManager* smgr);
//! destructor
virtual ~CXMeshFileLoader();
@ -40,10 +41,148 @@ public:
//! See IUnknown::drop() for more information.
virtual IAnimatedMesh* createMesh(irr::io::IReadFile* file);
struct SXTemplateMaterial
{
core::stringc Name; // template name from Xfile
video::SMaterial Material; // material
};
struct SXMesh
{
// this mesh contains triangulated texture data.
// because in an .x file, faces can be made of more than 3
// vertices, the indices data structure is triangulated during the
// loading process. The IndexCountPerFace array is filled during
// this triangulation process and stores how much indices belong to
// every face. This data structure can be ignored, because all data
// in this structure is triangulated.
core::stringc Name;
core::array< s32 > IndexCountPerFace; // default 3, but could be more
core::array<scene::SSkinMeshBuffer*> Buffers;
core::array<video::S3DVertex> Vertices;
core::array<u32> Indices;
core::array<u32> FaceIndices; // index of material for each face
core::array<video::SMaterial> Materials; // material array
};
private:
IMeshManipulator* Manipulator;
video::IVideoDriver* Driver;
bool load();
bool readFileIntoMemory();
bool parseFile();
bool parseDataObject();
bool parseDataObjectTemplate();
bool parseDataObjectFrame(CSkinnedMesh::SJoint *parent);
bool parseDataObjectTransformationMatrix(core::matrix4 &mat);
bool parseDataObjectMesh(SXMesh &mesh);
bool parseDataObjectSkinWeights(SXMesh &mesh);
bool parseDataObjectSkinMeshHeader();
bool parseDataObjectMeshNormals(SXMesh &mesh);
bool parseDataObjectMeshTextureCoords(SXMesh &mesh);
bool parseDataObjectMeshVertexColors(SXMesh &mesh);
bool parseDataObjectMeshMaterialList(SXMesh &mesh);
bool parseDataObjectMaterial(video::SMaterial& material);
bool parseDataObjectAnimationSet();
bool parseDataObjectAnimation();
bool parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint);
bool parseDataObjectTextureFilename(core::stringc& texturename);
bool parseUnknownDataObject();
//! places pointer to next begin of a token, and ignores comments
void findNextNoneWhiteSpace();
//! places pointer to next begin of a token, which must be a number,
// and ignores comments
void findNextNoneWhiteSpaceNumber();
//! returns next parseable token. Returns empty string if no token there
core::stringc getNextToken();
//! reads header of dataobject including the opening brace.
//! returns false if error happened, and writes name of object
//! if there is one
bool readHeadOfDataObject(core::stringc* outname=0);
//! checks for one following semicolons, returns false if they are not there
bool checkForOneFollowingSemicolons();
//! checks for two following semicolons, returns false if they are not there
bool checkForTwoFollowingSemicolons();
//! reads a x file style string
bool getNextTokenAsString(core::stringc& out);
void readUntilEndOfLine();
core::stringc stripPathFromString(core::stringc string, bool returnPath);
u16 readBinWord();
u32 readBinDWord();
s32 readInt();
f32 readFloat();
bool readVector2(core::vector2df& vec);
bool readVector3(core::vector3df& vec);
bool readRGB(video::SColorf& color);
bool readRGBA(video::SColorf& color);
bool readRGB(video::SColor& color);
bool readRGBA(video::SColor& color);
ISceneManager* SceneManager;
core::array<scene::SSkinMeshBuffer*> *Buffers;
core::array<CSkinnedMesh::SJoint*> *AllJoints;
CSkinnedMesh* AnimatedMesh;
io::IReadFile* file;
s32 MajorVersion;
s32 MinorVersion;
bool binary;
s32 binaryNumCount;
c8* Buffer;
s32 Size;
c8 FloatSize;
const c8* P;
c8* End;
bool ErrorHappened;
CSkinnedMesh::SJoint *CurFrame;
core::array<SXMesh*> Meshes;
core::array<SXTemplateMaterial> TemplateMaterials;
};
} // end namespace scene

View File

@ -719,6 +719,10 @@
RelativePath=".\..\..\include\IShadowVolumeSceneNode.h"
>
</File>
<File
RelativePath="..\..\include\ISkinnedMesh.h"
>
</File>
<File
RelativePath=".\..\..\include\ITerrainSceneNode.h"
>
@ -1687,14 +1691,6 @@
RelativePath=".\C3DSMeshFileLoader.h"
>
</File>
<File
RelativePath=".\CAnimatedMeshB3d.cpp"
>
</File>
<File
RelativePath=".\CAnimatedMeshB3d.h"
>
</File>
<File
RelativePath=".\CAnimatedMeshMD2.cpp"
>
@ -1712,11 +1708,19 @@
>
</File>
<File
RelativePath=".\CAnimatedMeshMS3D.cpp"
RelativePath=".\CB3DMeshFileLoader.cpp"
>
</File>
<File
RelativePath=".\CAnimatedMeshMS3D.h"
RelativePath=".\CB3DMeshFileLoader.h"
>
</File>
<File
RelativePath=".\CBSPMeshFileLoader.cpp"
>
</File>
<File
RelativePath=".\CBSPMeshFileLoader.h"
>
</File>
<File
@ -1735,14 +1739,6 @@
RelativePath=".\CCSMLoader.h"
>
</File>
<File
RelativePath=".\CDefaultMeshFormatLoader.cpp"
>
</File>
<File
RelativePath=".\CDefaultMeshFormatLoader.h"
>
</File>
<File
RelativePath=".\CDMFLoader.cpp"
>
@ -1759,6 +1755,14 @@
RelativePath=".\CLMTSMeshFileLoader.h"
>
</File>
<File
RelativePath=".\CMD2MeshFileLoader.cpp"
>
</File>
<File
RelativePath=".\CMD2MeshFileLoader.h"
>
</File>
<File
RelativePath=".\CMD3MeshFileLoader.cpp"
>
@ -1767,6 +1771,14 @@
RelativePath=".\CMD3MeshFileLoader.h"
>
</File>
<File
RelativePath=".\CMS3DMeshFileLoader.cpp"
>
</File>
<File
RelativePath=".\CMS3DMeshFileLoader.h"
>
</File>
<File
RelativePath=".\CMY3DHelper.h"
>
@ -1815,6 +1827,14 @@
RelativePath=".\CQ3LevelMesh.h"
>
</File>
<File
RelativePath=".\CSkinnedMesh.cpp"
>
</File>
<File
RelativePath=".\CSkinnedMesh.h"
>
</File>
<File
RelativePath="CXAnimationPlayer.cpp"
>
@ -1863,6 +1883,14 @@
RelativePath=".\CBillboardSceneNode.h"
>
</File>
<File
RelativePath=".\CBoneSceneNode.cpp"
>
</File>
<File
RelativePath=".\CBoneSceneNode.h"
>
</File>
<File
RelativePath=".\CCameraFPSSceneNode.cpp"
>

View File

@ -1,50 +1,47 @@
<?xml version="1.0"?>
<!DOCTYPE CodeBlocks_project_file>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="1"/>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Irrlicht"/>
<Option makefile="Makefile"/>
<Option makefile_is_custom="0"/>
<Option default_target="-1"/>
<Option compiler="0"/>
<Option title="Irrlicht" />
<Option pch_mode="0" />
<Option compiler="gcc" />
<Build>
<Target title="default">
<Option output="..\..\bin\win32-gcc\Irrlicht.dll"/>
<Option working_dir="."/>
<Option object_output=".objs"/>
<Option deps_output=".deps"/>
<Option type="3"/>
<Option compiler="0"/>
<Option createDefFile="1"/>
<Option createStaticLib="1"/>
<Option output="..\..\bin\win32-gcc\Irrlicht.dll" prefix_auto="0" extension_auto="0" />
<Option working_dir="..\..\bin\win32-gcc" />
<Option type="3" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Option createStaticLib="1" />
<Compiler>
<Add option="-O3"/>
<Add option="-O3" />
</Compiler>
</Target>
</Build>
<VirtualTargets>
<Add alias="All" targets="default;" />
</VirtualTargets>
<Compiler>
<Add option="-fexpensive-optimizations"/>
<Add option="-O3"/>
<Add option="-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIRRLICHT_EXPORTS"/>
<Add directory="..\..\include"/>
<Add directory="zlib"/>
<Add option="-fexpensive-optimizations" />
<Add option="-O3" />
<Add option="-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIRRLICHT_EXPORTS" />
<Add directory="..\..\include" />
<Add directory="zlib" />
</Compiler>
<Linker>
<Add library="kernel32"/>
<Add library="user32"/>
<Add library="gdi32"/>
<Add library="winspool"/>
<Add library="comdlg32"/>
<Add library="advapi32"/>
<Add library="shell32"/>
<Add library="ole32"/>
<Add library="oleaut32"/>
<Add library="uuid"/>
<Add library="odbc32"/>
<Add library="odbccp32"/>
<Add library="glu32"/>
<Add library="opengl32"/>
<Add library="kernel32" />
<Add library="user32" />
<Add library="gdi32" />
<Add library="winspool" />
<Add library="comdlg32" />
<Add library="advapi32" />
<Add library="shell32" />
<Add library="ole32" />
<Add library="oleaut32" />
<Add library="uuid" />
<Add library="odbc32" />
<Add library="odbccp32" />
<Add library="opengl32" />
</Linker>
<Unit filename="..\..\changes.txt">
<Option compilerVar="CPP"/>
@ -2587,434 +2584,248 @@
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\cdjpeg.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\cdjpeg.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\cdjpeg.h" />
<Unit filename="jpeglib\jcapimin.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcapistd.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jccoefct.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jccolor.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcdctmgr.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jchuff.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jchuff.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jchuff.h" />
<Unit filename="jpeglib\jcinit.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcmainct.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcmarker.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcmaster.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcomapi.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jconfig.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jconfig.h" />
<Unit filename="jpeglib\jcparam.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcphuff.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcprepct.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jcsample.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jctrans.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdapimin.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdapistd.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdatadst.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdatasrc.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdcoefct.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdcolor.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jdct.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdct.h" />
<Unit filename="jpeglib\jddctmgr.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdhuff.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jdhuff.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdhuff.h" />
<Unit filename="jpeglib\jdinput.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdmainct.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdmarker.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdmaster.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdmerge.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdphuff.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdpostct.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdsample.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jdtrans.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jerror.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jerror.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jerror.h" />
<Unit filename="jpeglib\jfdctflt.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jfdctfst.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jfdctint.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jidctflt.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jidctfst.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jidctint.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jidctred.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jinclude.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jinclude.h" />
<Unit filename="jpeglib\jmemmgr.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jmemnobs.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jmemsys.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jmorecfg.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jpegint.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jpeglib.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jmemsys.h" />
<Unit filename="jpeglib\jmorecfg.h" />
<Unit filename="jpeglib\jpegint.h" />
<Unit filename="jpeglib\jpeglib.h" />
<Unit filename="jpeglib\jquant1.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jquant2.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jutils.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="jpeglib\jversion.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="jpeglib\jversion.h" />
<Unit filename="libpng\png.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="libpng\png.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
</Unit>
<Unit filename="libpng\pngconf.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\png.h" />
<Unit filename="libpng\pngconf.h" />
<Unit filename="libpng\pngerror.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngget.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngmem.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngpread.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngread.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngrio.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngrtran.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngrutil.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngset.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngtrans.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngwio.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngwrite.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngwtran.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="libpng\pngwutil.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="os.cpp">
<Option compilerVar="CPP"/>
<Option target="default"/>
</Unit>
<Unit filename="os.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="os.cpp" />
<Unit filename="os.h" />
<Unit filename="zlib\adler32.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\compress.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\crc32.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\crc32.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\crc32.h" />
<Unit filename="zlib\deflate.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\deflate.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\deflate.h" />
<Unit filename="zlib\inffast.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\inffast.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\inffast.h" />
<Unit filename="zlib\inflate.c">
<Option compilerVar="CC"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\inftrees.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\inftrees.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\inftrees.h" />
<Unit filename="zlib\trees.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\trees.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\trees.h" />
<Unit filename="zlib\uncompr.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\zconf.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\zlib.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\zconf.h" />
<Unit filename="zlib\zlib.h" />
<Unit filename="zlib\zutil.c">
<Option compilerVar="CC"/>
<Option target="default"/>
</Unit>
<Unit filename="zlib\zutil.h">
<Option compilerVar="CPP"/>
<Option compile="0"/>
<Option link="0"/>
<Option target="default"/>
<Option compilerVar="CC" />
</Unit>
<Unit filename="zlib\zutil.h" />
<Extensions>
<code_completion />
<envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -1,7 +1,7 @@
VERSION = 1.3.1
# Irrlicht Engine 1.3.1
VERSION = 1.4RC
# Irrlicht Engine 1.4RC
# Makefile for Linux, created by N.Gebhardt.
#
#
# To use, just run:
#
# make
@ -14,12 +14,15 @@ VERSION = 1.3.1
# make sharedlib
# make install
#
# Please note that Irrlicht as shared lib is just experimental and
# Please note that Irrlicht as shared lib is just experimental and
# probably not tested.
#
#List of object files, separated based on engine architecture
IRROBJ = C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CAnimatedMeshMD2.o CAnimatedMeshMD3.o CMD3MeshFileLoader.o CAnimatedMeshMS3D.o CAnimatedMeshB3d.o CAnimatedMeshSceneNode.o CBillboardSceneNode.o CCameraFPSSceneNode.o CCameraMayaSceneNode.o CCameraSceneNode.o CColladaFileLoader.o CCSMLoader.o CDefaultMeshFormatLoader.o CDMFLoader.o CDummyTransformationSceneNode.o CEmptySceneNode.o CGeometryCreator.o CLightSceneNode.o CLMTSMeshFileLoader.o CMeshManipulator.o CMeshSceneNode.o CMetaTriangleSelector.o CMY3DMeshFileLoader.o COCTLoader.o COctTreeSceneNode.o COctTreeTriangleSelector.o CParticleAnimatedMeshSceneNodeEmitter.o CParticleBoxEmitter.o CParticleCylinderEmitter.o CParticleMeshEmitter.o CParticlePointEmitter.o CParticleRingEmitter.o CParticleSphereEmitter.o CParticleAttractionAffector.o CParticleFadeOutAffector.o CParticleGravityAffector.o CParticleRotationAffector.o CParticleSystemSceneNode.o CQ3LevelMesh.o CSceneCollisionManager.o CSceneManager.o CSceneNodeAnimatorCollisionResponse.o CSceneNodeAnimatorDelete.o CSceneNodeAnimatorFlyCircle.o CSceneNodeAnimatorFlyStraight.o CSceneNodeAnimatorFollowSpline.o CSceneNodeAnimatorRotation.o CSceneNodeAnimatorTexture.o CShadowVolumeSceneNode.o CSkyBoxSceneNode.o CSkyDomeSceneNode.o CTerrainSceneNode.o CTerrainTriangleSelector.o CCubeSceneNode.o CSphereSceneNode.o CTextSceneNode.o CTriangleBBSelector.o CTriangleSelector.o CWaterSurfaceSceneNode.o CXAnimationPlayer.o CXFileReader.o CXMeshFileLoader.o CMeshCache.o CDefaultSceneNodeAnimatorFactory.o CDefaultSceneNodeFactory.o CQuake3ShaderSceneNode.o
IRRMESHOBJ = CSkinnedMesh.o CBSPMeshFileLoader.o CMD2MeshFileLoader.o CMD3MeshFileLoader.o CMS3DMeshFileLoader.o CB3DMeshFileLoader.o CBoneSceneNode.o CBSPMeshFileLoader.o C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CAnimatedMeshMD2.o CAnimatedMeshMD3.o CMD3MeshFileLoader.o CAnimatedMeshSceneNode.o CColladaFileLoader.o CCSMLoader.o CDMFLoader.o CLMTSMeshFileLoader.o CMeshSceneNode.o CMY3DMeshFileLoader.o COCTLoader.o CQ3LevelMesh.o CXMeshFileLoader.o CQuake3ShaderSceneNode.o
IRROBJ = CBillboardSceneNode.o CCameraFPSSceneNode.o CCameraMayaSceneNode.o CCameraSceneNode.o CDummyTransformationSceneNode.o CEmptySceneNode.o CGeometryCreator.o CLightSceneNode.o CMeshManipulator.o CMetaTriangleSelector.o COctTreeSceneNode.o COctTreeTriangleSelector.o CSceneCollisionManager.o CSceneManager.o CShadowVolumeSceneNode.o CSkyBoxSceneNode.o CSkyDomeSceneNode.o CTerrainSceneNode.o CTerrainTriangleSelector.o CCubeSceneNode.o CSphereSceneNode.o CTextSceneNode.o CTriangleBBSelector.o CTriangleSelector.o CWaterSurfaceSceneNode.o CMeshCache.o CDefaultSceneNodeAnimatorFactory.o CDefaultSceneNodeFactory.o
IRRPARTICLEOBJ = CParticleAnimatedMeshSceneNodeEmitter.o CParticleBoxEmitter.o CParticleCylinderEmitter.o CParticleMeshEmitter.o CParticlePointEmitter.o CParticleRingEmitter.o CParticleSphereEmitter.o CParticleAttractionAffector.o CParticleFadeOutAffector.o CParticleGravityAffector.o CParticleRotationAffector.o CParticleSystemSceneNode.o
IRRANIMOBJ = CSceneNodeAnimatorCollisionResponse.o CSceneNodeAnimatorDelete.o CSceneNodeAnimatorFlyCircle.o CSceneNodeAnimatorFlyStraight.o CSceneNodeAnimatorFollowSpline.o CSceneNodeAnimatorRotation.o CSceneNodeAnimatorTexture.o
IRRVIDEOOBJ = COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLShaderMaterialRenderer.o COpenGLTexture.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D8Driver.o CD3D8NormalMapRenderer.o CD3D8ParallaxMapRenderer.o CD3D8ShaderMaterialRenderer.o CD3D8Texture.o CColorConverter.o CFPSCounter.o CImage.o CImageLoaderBMP.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderTGA.o CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o CNullDriver.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o CVideoModeList.o
IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryReadFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CZipReader.o CPakReader.o irrXML.o CAttributes.o
@ -30,7 +33,9 @@ JPEGLIBOBJ = jpeglib/jcapimin.o jpeglib/jcapistd.o jpeglib/jccoefct.o jpeglib/jc
LIBPNGOBJ = libpng/png.o libpng/pngerror.o libpng/pngget.o libpng/pngmem.o libpng/pngpread.o libpng/pngread.o libpng/pngrio.o libpng/pngrtran.o libpng/pngrutil.o libpng/pngset.o libpng/pngtrans.o libpng/pngwio.o libpng/pngwrite.o libpng/pngwtran.o libpng/pngwutil.o
# Next variable is for additional scene nodes etc. of customized Irrlicht versions
EXTRAOBJ =
LINKOBJ = $(IRROBJ) $(IRRVIDEOOBJ) $(IRRSWRENDEROBJ) $(IRRIOOBJ) $(IRROTHEROBJ) $(IRRGUIOBJ) $(ZLIBOBJ) $(JPEGLIBOBJ) $(LIBPNGOBJ) $(EXTRAOBJ)
LINKOBJ := $(IRRMESHOBJ) $(IRROBJ) $(IRRPARTICLEOBJ) $(IRRANIMOBJ) \
$(IRRVIDEOOBJ) $(IRRSWRENDEROBJ) $(IRRIOOBJ) $(IRROTHEROBJ) \
$(IRRGUIOBJ) $(ZLIBOBJ) $(JPEGLIBOBJ) $(LIBPNGOBJ) $(EXTRAOBJ)
###############
#Compiler flags
@ -99,7 +104,7 @@ install:
-include $(LINKOBJ:.o=.d)
help:
help:
@echo "Available targets for Irrlicht"
@echo " sharedlib: Build shared library Irrlicht.so for Linux"
@echo " staticlib: Build static library Irrlicht.a for Linux"
@ -110,7 +115,7 @@ help:
@echo ""
@echo " clean: Clean up directory"
# Cleans all temporary files and compilation results.
# Cleans all temporary files and compilation results.
clean:
$(RM) $(LINKOBJ) $(SHARED_LIB).$(VERSION) $(STATIC_LIB) $(LINKOBJ:.o=.d)