source: OGRE/trunk/ogrenew/OgreMain/src/OgreSubEntity.cpp @ 692

Revision 692, 14.7 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreSubEntity.h"
27
28#include "OgreEntity.h"
29#include "OgreSkeletonInstance.h"
30#include "OgreSceneManager.h"
31#include "OgreMaterialManager.h"
32#include "OgreSubMesh.h"
33#include "OgreTagPoint.h"
34#include "OgreLogManager.h"
35#include "OgreMesh.h"
36#include "OgreException.h"
37
38namespace Ogre {
39    //-----------------------------------------------------------------------
40    SubEntity::SubEntity (Entity* parent, SubMesh* subMeshBasis)
41        : Renderable(), mParentEntity(parent), mMaterialName("BaseWhite"),
42                mSubMesh(subMeshBasis)
43    {
44        mpMaterial = MaterialManager::getSingleton().getByName(mMaterialName);
45        mMaterialLodIndex = 0;
46        mVisible = true;
47        mSkelAnimVertexData = 0;
48                mSoftwareVertexAnimVertexData = 0;
49                mHardwareVertexAnimVertexData = 0;
50                mHardwarePoseCount = 0;
51
52
53
54    }
55    //-----------------------------------------------------------------------
56    SubEntity::~SubEntity()
57    {
58        if (mSkelAnimVertexData)
59            delete mSkelAnimVertexData;
60                if (mHardwareVertexAnimVertexData)
61                        delete mHardwareVertexAnimVertexData;
62                if (mSoftwareVertexAnimVertexData)
63                        delete mSoftwareVertexAnimVertexData;
64    }
65    //-----------------------------------------------------------------------
66    SubMesh* SubEntity::getSubMesh(void)
67    {
68        return mSubMesh;
69    }
70    //-----------------------------------------------------------------------
71    const String& SubEntity::getMaterialName(void) const
72    {
73        return mMaterialName;
74    }
75    //-----------------------------------------------------------------------
76    void SubEntity::setMaterialName( const String& name)
77    {
78
79        //String oldName = mMaterialName;
80        mMaterialName = name;
81        mpMaterial = MaterialManager::getSingleton().getByName(mMaterialName);
82
83        if (mpMaterial.isNull())
84        {
85            LogManager::getSingleton().logMessage("Can't assign material " + name +
86                " to SubEntity of " + mParentEntity->getName() + " because this "
87                "Material does not exist. Have you forgotten to define it in a "
88                ".material script?");
89            mpMaterial = MaterialManager::getSingleton().getByName("BaseWhite");
90            if (mpMaterial.isNull())
91            {
92                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material "
93                    "to SubEntity of " + mParentEntity->getName() + ". Did "
94                    "you forget to call MaterialManager::initialise()?",
95                    "SubEntity.setMaterialName");
96            }
97        }
98        // Ensure new material loaded (will not load again if already loaded)
99        mpMaterial->load();
100
101        // tell parent to reconsider material vertex processing options
102        mParentEntity->reevaluateVertexProcessing();
103
104
105    }
106    //-----------------------------------------------------------------------
107    const MaterialPtr& SubEntity::getMaterial(void) const
108    {
109        return mpMaterial;
110    }
111    //-----------------------------------------------------------------------
112    Technique* SubEntity::getTechnique(void) const
113    {
114        return mpMaterial->getBestTechnique(mMaterialLodIndex);
115    }
116    //-----------------------------------------------------------------------
117    void SubEntity::getRenderOperation(RenderOperation& op)
118    {
119                // Use LOD
120        mSubMesh->_getRenderOperation(op, mParentEntity->mMeshLodIndex);
121                // Deal with any vertex data overrides
122                op.vertexData = getVertexDataForBinding();
123
124    }
125        //-----------------------------------------------------------------------
126        VertexData* SubEntity::getVertexDataForBinding(void)
127        {
128                if (mSubMesh->useSharedVertices)
129                {
130                        return mParentEntity->getVertexDataForBinding();
131                }
132                else
133                {
134                        Entity::VertexDataBindChoice c =
135                                mParentEntity->chooseVertexDataForBinding(
136                                        mSubMesh->getVertexAnimationType() != VAT_NONE);
137                        switch(c)
138                        {
139                        case Entity::BIND_ORIGINAL:
140                                return mSubMesh->vertexData;
141                        case Entity::BIND_HARDWARE_MORPH:
142                                return mHardwareVertexAnimVertexData;
143                        case Entity::BIND_SOFTWARE_MORPH:
144                                return mSoftwareVertexAnimVertexData;
145                        case Entity::BIND_SOFTWARE_SKELETAL:
146                                return mSkelAnimVertexData;
147                        };
148                        // keep compiler happy
149                        return mSubMesh->vertexData;
150
151                }
152        }
153    //-----------------------------------------------------------------------
154    void SubEntity::getWorldTransforms(Matrix4* xform) const
155    {
156        if (!mParentEntity->mNumBoneMatrices ||
157            !mParentEntity->isHardwareAnimationEnabled())
158        {
159            // No skeletal animation, or software skinning
160            *xform = mParentEntity->_getParentNodeFullTransform();
161        }
162        else
163        {
164            // Hardware skinning, pass all actually used matrices
165            const Mesh::IndexMap& indexMap = mSubMesh->useSharedVertices ?
166                mSubMesh->parent->sharedBlendIndexToBoneIndexMap : mSubMesh->blendIndexToBoneIndexMap;
167            assert(indexMap.size() <= mParentEntity->mNumBoneMatrices);
168
169            if (mParentEntity->_isSkeletonAnimated())
170            {
171                // Bones, use cached matrices built when Entity::_updateRenderQueue was called
172                assert(mParentEntity->mBoneWorldMatrices);
173
174                Mesh::IndexMap::const_iterator it, itend;
175                itend = indexMap.end();
176                for (it = indexMap.begin(); it != itend; ++it, ++xform)
177                {
178                    *xform = mParentEntity->mBoneWorldMatrices[*it];
179                }
180            }
181            else
182            {
183                // All animations disabled, use parent entity world transform only
184                std::fill_n(xform, indexMap.size(), mParentEntity->_getParentNodeFullTransform());
185            }
186        }
187    }
188    //-----------------------------------------------------------------------
189    const Quaternion& SubEntity::getWorldOrientation(void) const
190    {
191        return mParentEntity->mParentNode->_getDerivedOrientation();
192    }
193    //-----------------------------------------------------------------------
194    const Vector3& SubEntity::getWorldPosition(void) const
195    {
196        return mParentEntity->mParentNode->_getDerivedPosition();
197    }
198
199    //-----------------------------------------------------------------------
200    unsigned short SubEntity::getNumWorldTransforms(void) const
201    {
202        if (!mParentEntity->mNumBoneMatrices ||
203            !mParentEntity->isHardwareAnimationEnabled())
204        {
205            // No skeletal animation, or software skinning
206            return 1;
207        }
208        else
209        {
210            // Hardware skinning, pass all actually used matrices
211            const Mesh::IndexMap& indexMap = mSubMesh->useSharedVertices ?
212                mSubMesh->parent->sharedBlendIndexToBoneIndexMap : mSubMesh->blendIndexToBoneIndexMap;
213            assert(indexMap.size() <= mParentEntity->mNumBoneMatrices);
214
215            return static_cast<unsigned short>(indexMap.size());
216        }
217    }
218    //-----------------------------------------------------------------------
219    Real SubEntity::getSquaredViewDepth(const Camera* cam) const
220    {
221        Node* n = mParentEntity->getParentNode();
222        assert(n);
223        return n->getSquaredViewDepth(cam);
224    }
225    //-----------------------------------------------------------------------
226    bool SubEntity::getNormaliseNormals(void) const
227    {
228        return mParentEntity->mNormaliseNormals;
229    }
230    //-----------------------------------------------------------------------
231    const LightList& SubEntity::getLights(void) const
232    {
233        SceneNode* n = mParentEntity->getParentSceneNode();
234        assert(n);
235        return n->findLights(mParentEntity->getBoundingRadius());
236    }
237    //-----------------------------------------------------------------------
238    void SubEntity::setVisible(bool visible)
239    {
240        mVisible = visible;
241    }
242    //-----------------------------------------------------------------------
243    bool SubEntity::isVisible(void) const
244    {
245        return mVisible;
246
247    }
248    //-----------------------------------------------------------------------
249    void SubEntity::prepareTempBlendBuffers(void)
250    {
251                if (mSubMesh->useSharedVertices)
252                        return;
253
254        if (mSkelAnimVertexData)
255        {
256            delete mSkelAnimVertexData;
257            mSkelAnimVertexData = 0;
258        }
259                if (mSoftwareVertexAnimVertexData)
260                {
261                        delete mSoftwareVertexAnimVertexData;
262                        mSoftwareVertexAnimVertexData = 0;
263                }
264                if (mHardwareVertexAnimVertexData)
265                {
266                        delete mHardwareVertexAnimVertexData;
267                        mHardwareVertexAnimVertexData = 0;
268                }
269
270                if (!mSubMesh->useSharedVertices)
271                {
272                        if (mSubMesh->getVertexAnimationType() != VAT_NONE)
273                        {
274                                // Create temporary vertex blend info
275                                // Prepare temp vertex data if needed
276                                // Clone without copying data, remove blending info
277                                // (since blend is performed in software)
278                                mSoftwareVertexAnimVertexData =
279                                        mParentEntity->cloneVertexDataRemoveBlendInfo(mSubMesh->vertexData);
280                                mParentEntity->extractTempBufferInfo(mSoftwareVertexAnimVertexData, &mTempVertexAnimInfo);
281
282                                // Also clone for hardware usage, don't remove blend info since we'll
283                                // need it if we also hardware skeletally animate
284                                mHardwareVertexAnimVertexData = mSubMesh->vertexData->clone(false);
285                        }
286
287                        if (mParentEntity->hasSkeleton())
288                        {
289                                // Create temporary vertex blend info
290                                // Prepare temp vertex data if needed
291                                // Clone without copying data, remove blending info
292                                // (since blend is performed in software)
293                                mSkelAnimVertexData =
294                                        mParentEntity->cloneVertexDataRemoveBlendInfo(mSubMesh->vertexData);
295                                mParentEntity->extractTempBufferInfo(mSkelAnimVertexData, &mTempSkelAnimInfo);
296
297                        }
298                }
299    }
300    //-----------------------------------------------------------------------
301    bool SubEntity::getCastsShadows(void) const
302    {
303        return mParentEntity->getCastShadows();
304    }
305        //-----------------------------------------------------------------------
306        VertexData* SubEntity::_getSkelAnimVertexData(void)
307        {
308                assert (mSkelAnimVertexData && "Not software skinned!");
309                return mSkelAnimVertexData;
310        }
311        //-----------------------------------------------------------------------
312        VertexData* SubEntity::_getSoftwareVertexAnimVertexData(void)
313        {
314                assert (mSoftwareVertexAnimVertexData && "Not vertex animated!");
315                return mSoftwareVertexAnimVertexData;
316        }
317        //-----------------------------------------------------------------------
318        VertexData* SubEntity::_getHardwareVertexAnimVertexData(void)
319        {
320                assert (mHardwareVertexAnimVertexData && "Not vertex animated!");
321                return mHardwareVertexAnimVertexData;
322        }
323        //-----------------------------------------------------------------------
324        TempBlendedBufferInfo* SubEntity::_getSkelAnimTempBufferInfo(void)
325        {
326                return &mTempSkelAnimInfo;
327        }
328        //-----------------------------------------------------------------------
329        TempBlendedBufferInfo* SubEntity::_getVertexAnimTempBufferInfo(void)
330        {
331                return &mTempVertexAnimInfo;
332        }
333        //-----------------------------------------------------------------------
334        void SubEntity::_updateCustomGpuParameter(
335                const GpuProgramParameters::AutoConstantEntry& constantEntry,
336                GpuProgramParameters* params) const
337        {
338                if (constantEntry.paramType == GpuProgramParameters::ACT_ANIMATION_PARAMETRIC)
339                {
340                        // Set up to 4 values, or up to limit of hardware animation entries
341                        // Pack into 4-element constants offset based on constant data index
342                        // If there are more than 4 entries, this will be called more than once
343                        Vector4 val(0.0f,0.0f,0.0f,0.0f);
344
345                        size_t animIndex = constantEntry.data * 4;
346                        for (size_t i = 0; i < 4 &&
347                                animIndex < mHardwareVertexAnimVertexData->hwAnimationDataList.size();
348                                ++i, ++animIndex)
349                        {
350                                val.val[i] =
351                                        mHardwareVertexAnimVertexData->hwAnimationDataList[animIndex].parametric;
352                        }
353                        // set the parametric morph value
354                        params->setConstant(constantEntry.index, val);
355                }
356                else
357                {
358                        // default
359                        return Renderable::_updateCustomGpuParameter(constantEntry, params);
360                }
361        }
362        //-----------------------------------------------------------------------------
363        void SubEntity::_markBuffersUnusedForAnimation(void)
364        {
365                mVertexAnimationAppliedThisFrame = false;
366        }
367        //-----------------------------------------------------------------------------
368        void SubEntity::_markBuffersUsedForAnimation(void)
369        {
370                mVertexAnimationAppliedThisFrame = true;
371        }
372        //-----------------------------------------------------------------------------
373        void SubEntity::_restoreBuffersForUnusedAnimation(bool hardwareAnimation)
374        {
375                // Rebind original positions if:
376                //  We didn't apply any animation and
377                //    We're morph animated (hardware binds keyframe, software is missing)
378                //    or we're pose animated and software (hardware is fine, still bound)
379                if (mSubMesh->getVertexAnimationType() != VAT_NONE &&
380                        !mSubMesh->useSharedVertices &&
381                        !mVertexAnimationAppliedThisFrame &&
382                        (!hardwareAnimation || mSubMesh->getVertexAnimationType() == VAT_MORPH))
383                {
384                        const VertexElement* srcPosElem =
385                                mSubMesh->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
386                        HardwareVertexBufferSharedPtr srcBuf =
387                                mSubMesh->vertexData->vertexBufferBinding->getBuffer(
388                                srcPosElem->getSource());
389
390                        // Bind to software
391                        const VertexElement* destPosElem =
392                                mSoftwareVertexAnimVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
393                        mSoftwareVertexAnimVertexData->vertexBufferBinding->setBinding(
394                                destPosElem->getSource(), srcBuf);
395
396                }
397        }
398
399
400}
Note: See TracBrowser for help on using the repository browser.