From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/lod__character__builder_8cpp-source.html | 313 +++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 docs/doxygen/nel/lod__character__builder_8cpp-source.html (limited to 'docs/doxygen/nel/lod__character__builder_8cpp-source.html') diff --git a/docs/doxygen/nel/lod__character__builder_8cpp-source.html b/docs/doxygen/nel/lod__character__builder_8cpp-source.html new file mode 100644 index 00000000..edc0e0dd --- /dev/null +++ b/docs/doxygen/nel/lod__character__builder_8cpp-source.html @@ -0,0 +1,313 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

lod_character_builder.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "std3d.h"
+00027 
+00028 #include "nel/misc/debug.h"
+00029 #include "3d/lod_character_builder.h"
+00030 #include "3d/scene.h"
+00031 #include "3d/skeleton_shape.h"
+00032 #include "3d/mesh.h"
+00033 #include "3d/skeleton_model.h"
+00034 
+00035 
+00036 using namespace std;
+00037 using namespace NLMISC;
+00038 
+00039 
+00040 namespace NL3D 
+00041 {
+00042 
+00043 
+00044 // ***************************************************************************
+00045 CLodCharacterBuilder::CLodCharacterBuilder()
+00046 {
+00047         _SkeletonShape= NULL;
+00048         _LodBuild= NULL;
+00049         _TmpScene= NULL;
+00050 }
+00051 // ***************************************************************************
+00052 CLodCharacterBuilder::~CLodCharacterBuilder()
+00053 {
+00054         // release the scene
+00055         if(_TmpScene)
+00056         {
+00057                 _TmpScene->release();
+00058                 delete _TmpScene;
+00059                 _TmpScene= NULL;
+00060         }
+00061 }
+00062 
+00063 // ***************************************************************************
+00064 void                    CLodCharacterBuilder::setShape(const std::string &name, CSkeletonShape *skeletonShape, CLodCharacterShapeBuild *lodBuild)
+00065 {
+00066         nlassert(skeletonShape);
+00067         nlassert(lodBuild);
+00068 
+00069         // SmartPtr the skeleton Shape (NB: important because skeletonModel use it)
+00070         _SkeletonShape= skeletonShape;
+00071         // a std ptr.
+00072         _LodBuild= lodBuild;
+00073 
+00074         // Remap bone, with help of lodBuild and skeleton names.
+00075         _BoneRemap.resize(lodBuild->BonesNames.size());
+00076         for(uint i=0; i<_BoneRemap.size(); i++)
+00077         {
+00078                 const std::string       &boneName= lodBuild->BonesNames[i];
+00079                 sint32  boneId= _SkeletonShape->getBoneIdByName(boneName);
+00080                 // If not found
+00081                 if(boneId<0)
+00082                 {
+00083                         nlwarning("Not found a bone in the skeleton Shape: %s", boneName.c_str());
+00084                         // use root bone.
+00085                         _BoneRemap[i]= 0;
+00086                 }
+00087                 else
+00088                         // remap
+00089                         _BoneRemap[i]= boneId;
+00090         }
+00091 
+00092         // build basics
+00093         _LodCharacterShape.buildMesh(name, *_LodBuild);
+00094 
+00095         // Build a scene, for addAnim purpose
+00096         if(!_TmpScene)
+00097         {
+00098                 _TmpScene= new CScene;
+00099                 // Must init Statics for scene (because use it in addAnim). NB: never mind if done twice.
+00100                 CScene::registerBasics();
+00101                 // init scene travs
+00102                 _TmpScene->initDefaultTravs();
+00103                 // Don't add any user trav.
+00104                 // init default Roots.
+00105                 _TmpScene->initDefaultRoots();
+00106                 // Don't Set driver/viewport
+00107                 // Init the world instance group
+00108                 _TmpScene->initGlobalnstanceGroup();
+00109                 // Init coarse mesh manager
+00110                 _TmpScene->initCoarseMeshManager ();
+00111                 // init QuadGridClipManager
+00112                 _TmpScene->initQuadGridClipManager ();
+00113         }
+00114 }
+00115 
+00116 
+00117 // ***************************************************************************
+00118 void                    CLodCharacterBuilder::addAnim(const char *animName, CAnimation *animation, float frameRate)
+00119 {
+00120         nlassert(frameRate>0);
+00121         nlassert(animation);
+00122 
+00123         /*      Create a Scene, a skeletonModel, an animation set, and a channel mixer to play the animation
+00124                 NB: no render is made and no driver is created. The scene is just here for correct creation of the skeleton
+00125                 Yoyo: This is a tricky way, but I found it the easier one...
+00126         */
+00127 
+00128         // Create Components necesssary to play the animation
+00129         //==========================
+00130 
+00131         // create an animationSet, and a channelMixer.
+00132         //--------------
+00133         // build an animation set with the only one animation. This animation will be deleted with the animationSet
+00134         CAnimationSet   *tmpAnimationSet= new CAnimationSet;
+00135         tmpAnimationSet->addAnimation(animName, animation);
+00136         tmpAnimationSet->build();
+00137         // Build a channelMixer.
+00138         CChannelMixer   *tmpChannelMixer= new CChannelMixer;
+00139         tmpChannelMixer->setAnimationSet(tmpAnimationSet);
+00140 
+00141 
+00142         // create a skeleton Model for animation
+00143         //---------------
+00144         CSkeletonModel  *skeleton= (CSkeletonModel*)_SkeletonShape->createInstance(*_TmpScene);
+00145         // and skeleton it with animation
+00146         skeleton->registerToChannelMixer(tmpChannelMixer, "");
+00147         // activate the anim
+00148         uint animID = tmpAnimationSet->getAnimationIdByName(animName);
+00149         nlassert(animID != CAnimationSet::NotFound);
+00150         tmpChannelMixer->setSlotAnimation(0, animID);
+00151 
+00152 
+00153         // Build Dst Animation basics.
+00154         //--------------
+00155         CLodCharacterShape::CAnimBuild  dstAnim;
+00156         dstAnim.Name= animName;
+00157         dstAnim.AnimLength= animation->getEndTime();
+00158         dstAnim.NumKeys= (uint)ceil(dstAnim.AnimLength * frameRate);
+00159         dstAnim.NumKeys= max(1U, dstAnim.NumKeys);
+00160         // resize array.
+00161         dstAnim.Keys.resize(_LodCharacterShape.getNumVertices() * dstAnim.NumKeys);
+00162 
+00163 
+00164         // Bake the animation
+00165         //==========================
+00166         double  time=0;
+00167         double  dt= 1.0/(double)frameRate;
+00168         uint64  evalDetaiDate= 0;
+00169         for(uint i=0; i<dstAnim.NumKeys; i++, time+= dt)
+00170         {
+00171                 // clamp the time
+00172                 time= min(time, (double)dstAnim.AnimLength);
+00173 
+00174                 // setup the channelMixer time
+00175                 tmpChannelMixer->setSlotTime(0, (float)time);
+00176 
+00177                 // Eval the channelMixer, both global and detail
+00178                 tmpChannelMixer->eval(false);
+00179                 tmpChannelMixer->eval(true, evalDetaiDate++);
+00180 
+00181                 // Use the skeleton model to compute bone skin matrix, supposing an identity skeleton worldMatrix
+00182                 skeleton->computeAllBones(CMatrix::Identity);
+00183 
+00184                 // apply the skinning from the current skeleton state
+00185                 applySkin(skeleton, &dstAnim.Keys[i*_LodCharacterShape.getNumVertices()]);
+00186         }
+00187 
+00188 
+00189         // Add the animation to the lod
+00190         //==========================
+00191         _LodCharacterShape.addAnim(dstAnim);
+00192 
+00193 
+00194         // Delete
+00195         //==========================
+00196         // release the skeleton
+00197         _TmpScene->deleteModel(skeleton);
+00198         // delete the channelMixer
+00199         delete tmpChannelMixer;
+00200         // delete the animationSet
+00201         delete tmpAnimationSet;
+00202 }
+00203 
+00204 
+00205 // ***************************************************************************
+00206 void                    CLodCharacterBuilder::applySkin(CSkeletonModel *skeleton, CVector       *dstVertices)
+00207 {
+00208         uint    numVerts= _LodBuild->Vertices.size();
+00209 
+00210         // for all vertices.
+00211         for(uint i=0; i<numVerts; i++)
+00212         {
+00213                 CMesh::CSkinWeight      &skinWgt= _LodBuild->SkinWeights[i];
+00214                 CVector                         &srcVert= _LodBuild->Vertices[i];
+00215                 CVector                         &dstVert= dstVertices[i];
+00216                 dstVert= CVector::Null;
+00217                 // parse all Weights, and add influence.
+00218                 for(uint j=0; j<NL3D_MESH_SKINNING_MAX_MATRIX; j++)
+00219                 {
+00220                         float   wgt= skinWgt.Weights[j];
+00221 
+00222                         if(wgt==0)
+00223                         {
+00224                                 // this should not happen, at least weight 0 should have an influence.
+00225                                 if(j==0)
+00226                                         dstVert= srcVert;
+00227                                 // no more influence for this vertex.
+00228                                 break;
+00229                         }
+00230                         else
+00231                         {
+00232                                 // Get the skeleton bone to read.
+00233                                 uint    boneId= _BoneRemap[skinWgt.MatrixId[j]];
+00234                                 // Get the computed matrix from the skeleton.
+00235                                 const   CMatrix &boneMat= skeleton->Bones[boneId].getBoneSkinMatrix();
+00236                                 // Add the influence of this bone.
+00237                                 dstVert+= (boneMat * srcVert) * wgt;
+00238                         }
+00239                 }
+00240         }
+00241 }
+00242 
+00243 
+00244 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1