Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/ogrebullet/Collisions/Utils/OgreBulletCollisionsMeshToShapeConverter.cpp @ 2274

Last change on this file since 2274 was 2192, checked in by rgrieder, 16 years ago

Reverted all changes of attempt to update physics branch.

  • Property svn:eol-style set to native
File size: 24.8 KB
RevLine 
[1985]1/***************************************************************************
2
3This source file is part of OGREBULLET
4(Object-oriented Graphics Rendering Engine Bullet Wrapper)
5For the latest info, see http://www.ogre3d.org/phpBB2addons/viewforum.php?f=10
6
7Copyright (c) 2007 tuan.kuranes@gmail.com (Use it Freely, even Statically, but have to contribute any changes)
8
9
10
11This program is free software; you can redistribute it and/or modify it under
12the terms of the GPL General Public License with runtime exception as published by the Free Software
13Foundation; either version 2 of the License, or (at your option) any later
14version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GPL General Public License with runtime exception for more details.
19
20You should have received a copy of the GPL General Public License with runtime exception along with
21this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22Place - Suite 330, Boston, MA 02111-1307, USA, or go to
23http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24-----------------------------------------------------------------------------
25*/
26
27#include "OgreBulletCollisions.h"
28
29#include "Utils/OgreBulletCollisionsMeshToShapeConverter.h"
30
31#include "Shapes/OgreBulletCollisionsTrimeshShape.h"
32#include "Shapes/OgreBulletCollisionsCylinderShape.h"
33#include "Shapes/OgreBulletCollisionsSphereShape.h"
34#include "Shapes/OgreBulletCollisionsBoxShape.h"
35#include "Shapes/OgreBulletCollisionsConvexHullShape.h"
36#include "Shapes/OgreBulletCollisionsCapsuleShape.h"
37
38using namespace OgreBulletCollisions;
39using namespace Ogre;
40
41//------------------------------------------------------------------------------------------------
42void VertexIndexToShape::addStaticVertexData(const VertexData *vertex_data)
43{
44        if (!vertex_data) 
45        return;
46
47        const VertexData *data = vertex_data;
48
49        const unsigned int prev_size = mVertexCount;
50    mVertexCount += (unsigned int)data->vertexCount;
51
52    Ogre::Vector3* tmp_vert = new Ogre::Vector3[mVertexCount];
53        if (mVertexBuffer)
54        {
55                memcpy(tmp_vert, mVertexBuffer, sizeof(Vector3) * prev_size);
56                delete[] mVertexBuffer;
57        }
58        mVertexBuffer = tmp_vert;
59
60        // Get the positional buffer element
61    {   
62        const Ogre::VertexElement* posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);                       
63        Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
64        const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
65
66            unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
67            float* pReal;
68        Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size];
69        const unsigned int vertexCount = (unsigned int)data->vertexCount;
70            for(unsigned int j = 0; j < vertexCount; ++j)
71            {
72                    posElem->baseVertexPointerToElement(vertex, &pReal);
73            vertex += vSize;
74
75                    curVertices->x = (*pReal++);
76                    curVertices->y = (*pReal++);
77                    curVertices->z = (*pReal++);
78
79                    *curVertices = mTransform * (*curVertices);
80           
81            curVertices++;
82        }
83            vbuf->unlock();
84    }
85}
86
87//------------------------------------------------------------------------------------------------
88void VertexIndexToShape::addAnimatedVertexData(const Ogre::VertexData *vertex_data,
89                                                                                           const Ogre::VertexData *blend_data,
90                                                                                           const Ogre::Mesh::IndexMap *indexMap)
91{       
92        // Get the bone index element
93        assert(vertex_data);
94
95        const VertexData *data = blend_data;
96        const unsigned int prev_size = mVertexCount;
97        mVertexCount += (unsigned int)data->vertexCount;
98        Ogre::Vector3* tmp_vert = new Ogre::Vector3[mVertexCount];
99        if (mVertexBuffer)
100        {
101                memcpy(tmp_vert, mVertexBuffer, sizeof(Vector3) * prev_size);
102                delete[] mVertexBuffer;
103        }
104        mVertexBuffer = tmp_vert;
105
106        // Get the positional buffer element
107        {       
108                const Ogre::VertexElement* posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);       
109                assert (posElem);
110                Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
111                const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
112
113                unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
114                float* pReal;
115                Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size];
116                const unsigned int vertexCount = (unsigned int)data->vertexCount;
117                for(unsigned int j = 0; j < vertexCount; ++j)
118                {
119                        posElem->baseVertexPointerToElement(vertex, &pReal);
120                        vertex += vSize;
121
122                        curVertices->x = (*pReal++);
123                        curVertices->y = (*pReal++);
124                        curVertices->z = (*pReal++);
125
126                        *curVertices = mTransform * (*curVertices);
127
128                        curVertices++;
129                }
130                vbuf->unlock();
131        }
132        {
133                const Ogre::VertexElement* bneElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_BLEND_INDICES);
134                assert (bneElem);
135               
136                Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(bneElem->getSource());
137                const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
138                unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
139
140                unsigned char* pBone;
141
142                if (!mBoneIndex)
143                        mBoneIndex = new BoneIndex();   
144                BoneIndex::iterator i;
145
146                Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size];
147
148                const unsigned int vertexCount = (unsigned int)vertex_data->vertexCount;
149                for(unsigned int j = 0; j < vertexCount; ++j)
150                {
151                        bneElem->baseVertexPointerToElement(vertex, &pBone);
152                        vertex += vSize;
153
154                        const unsigned char currBone = (indexMap) ? (*indexMap)[*pBone] : *pBone;
155                        i = mBoneIndex->find (currBone);
156                        Vector3Array* l = 0;
157                        if (i == mBoneIndex->end())
158                        {
159                                l = new Vector3Array;
160                                mBoneIndex->insert(BoneKeyIndex(currBone, l));
161                        }                                               
162                        else 
163                        {
164                                l = i->second;
165                        }
166
167                        l->push_back(*curVertices);
168
169                        curVertices++;
170                }
171                vbuf->unlock(); 
172        }
173}
174
175//------------------------------------------------------------------------------------------------
176void VertexIndexToShape::addIndexData(IndexData *data, const unsigned int offset)
177{
178    const unsigned int prev_size = mIndexCount;
179    mIndexCount += (unsigned int)data->indexCount;
180
181        unsigned int* tmp_ind = new unsigned int[mIndexCount];
182        if (mIndexBuffer)
183        {
184                memcpy (tmp_ind, mIndexBuffer, sizeof(unsigned int) * prev_size);
185                delete[] mIndexBuffer;
186        }
187        mIndexBuffer = tmp_ind;
188
189        const unsigned int numTris = (unsigned int) data->indexCount / 3;
190        HardwareIndexBufferSharedPtr ibuf = data->indexBuffer; 
191        const bool use32bitindexes = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT);
192    unsigned int index_offset = prev_size;
193
194        if (use32bitindexes) 
195    {
196        const unsigned int* pInt = static_cast<unsigned int*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
197        for(unsigned int k = 0; k < numTris; ++k)
198        {
199            mIndexBuffer[index_offset ++] = offset + *pInt++;
200            mIndexBuffer[index_offset ++] = offset + *pInt++;
201            mIndexBuffer[index_offset ++] = offset + *pInt++;
202        }
203        ibuf->unlock();
204    }
205        else 
206    {
207        const unsigned short* pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
208                for(unsigned int k = 0; k < numTris; ++k)
209        {
210            mIndexBuffer[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
211            mIndexBuffer[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
212            mIndexBuffer[index_offset ++] = offset + static_cast<unsigned int> (*pShort++);
213        }
214        ibuf->unlock();
215    }
216
217}
218//------------------------------------------------------------------------------------------------
219Real VertexIndexToShape::getRadius()
220{
221        if (mBoundRadius == (-1))
222        {
223                getSize();
224                mBoundRadius = (std::max(mBounds.x,std::max(mBounds.y,mBounds.z)) * 0.5);
225        }
226        return mBoundRadius;
227}
228//------------------------------------------------------------------------------------------------
229Vector3 VertexIndexToShape::getSize()
230{
231    const unsigned int vCount = getVertexCount();
232        if (mBounds == Ogre::Vector3(-1,-1,-1) && vCount > 0)
233        {
234
235                const Ogre::Vector3 * const v = getVertices();
236
237        Ogre::Vector3 vmin(v[0]);
238        Ogre::Vector3 vmax(v[0]);
239
240                for(unsigned int j = 1; j < vCount; j++)
241                {
242                        vmin.x = std::min(vmin.x, v[j].x);
243                        vmin.y = std::min(vmin.y, v[j].y);
244                        vmin.z = std::min(vmin.z, v[j].z);
245
246                        vmax.x = std::max(vmax.x, v[j].x);
247                        vmax.y = std::max(vmax.y, v[j].y);
248                        vmax.z = std::max(vmax.z, v[j].z);
249                }
250
251                mBounds.x = vmax.x - vmin.x;
252                mBounds.y = vmax.y - vmin.y;
253                mBounds.z = vmax.z - vmin.z;
254        }
255
256        return mBounds;
257}
258//------------------------------------------------------------------------------------------------
259const Ogre::Vector3* VertexIndexToShape::getVertices()
260{
261        return mVertexBuffer;
262}
263//------------------------------------------------------------------------------------------------
264unsigned int VertexIndexToShape::getVertexCount()
265{
266        return mVertexCount;
267}
268//------------------------------------------------------------------------------------------------
269const unsigned int* VertexIndexToShape::getIndices()
270{
271        return mIndexBuffer;
272}
273//------------------------------------------------------------------------------------------------
274unsigned int VertexIndexToShape::getIndexCount()
275{
276        return mIndexCount;
277}
278
279//------------------------------------------------------------------------------------------------
280SphereCollisionShape* VertexIndexToShape::createSphere()
281{
282        const Ogre::Real rad = getRadius();
283        assert((rad > 0.0) && 
284        ("Sphere radius must be greater than zero"));
285    SphereCollisionShape* shape = new SphereCollisionShape(rad);
286
287    return shape;
288}
289//------------------------------------------------------------------------------------------------
290BoxCollisionShape* VertexIndexToShape::createBox()
291{
292        const Ogre::Vector3 sz = getSize();
293
294        assert((sz.x > 0.0) && (sz.y > 0.0) && (sz.y > 0.0) && 
295        ("Size of box must be greater than zero on all axes"));
296
297        BoxCollisionShape* shape = new BoxCollisionShape(sz);
298        return shape;
299}
300//------------------------------------------------------------------------------------------------
301CylinderCollisionShape* VertexIndexToShape::createCylinder()
302{
303    const Ogre::Vector3 sz = getSize();
304
305    assert((sz.x > 0.0) && (sz.y > 0.0) && (sz.y > 0.0) && 
306        ("Size of Cylinder must be greater than zero on all axes"));
307
308    CylinderCollisionShape* shape = new CylinderCollisionShape(sz, Vector3::UNIT_X);
309    return shape;
310}
311//------------------------------------------------------------------------------------------------
312ConvexHullCollisionShape* VertexIndexToShape::createConvex()
313{
314    assert(mVertexCount && (mIndexCount >= 6) && 
315        ("Mesh must have some vertices and at least 6 indices (2 triangles)"));
316
317    return new ConvexHullCollisionShape(&mVertexBuffer[0].x, mVertexCount, sizeof(Vector3));
318}
319//------------------------------------------------------------------------------------------------
320TriangleMeshCollisionShape* VertexIndexToShape::createTrimesh()
321{
322        assert(mVertexCount && (mIndexCount >= 6) && 
323        ("Mesh must have some vertices and at least 6 indices (2 triangles)"));
324
325        return new TriangleMeshCollisionShape(mVertexBuffer, mVertexCount,mIndexBuffer, mIndexCount);
326}
327//------------------------------------------------------------------------------------------------
328VertexIndexToShape::~VertexIndexToShape()
329{
330        delete[] mVertexBuffer;
331        delete[] mIndexBuffer;
332
333        if (mBoneIndex)
334        {
335                for(BoneIndex::iterator i = mBoneIndex->begin();
336            i != mBoneIndex->end();
337            ++i)
338                {
339                        delete i->second;
340                }
341                delete mBoneIndex;
342        }
343}
344//------------------------------------------------------------------------------------------------
345VertexIndexToShape::VertexIndexToShape(const Matrix4 &transform) :
346        mVertexBuffer (0),
347        mIndexBuffer (0),
348        mVertexCount (0),
349        mIndexCount (0),
350        mBounds (Vector3(-1,-1,-1)),
351        mBoundRadius (-1),
352        mBoneIndex (0),
353        mTransform (transform)
354{       
355}
356//------------------------------------------------------------------------------------------------
357StaticMeshToShapeConverter::StaticMeshToShapeConverter() :
358VertexIndexToShape(),
359        mEntity (0),
360        mNode (0)
361{
362}
363//------------------------------------------------------------------------------------------------
364StaticMeshToShapeConverter::~StaticMeshToShapeConverter()
365{
366}
367//------------------------------------------------------------------------------------------------
368StaticMeshToShapeConverter::StaticMeshToShapeConverter(Entity *entity,  const Matrix4 &transform) :
369        VertexIndexToShape(transform),
370        mEntity (0),
371        mNode (0)
372{
373        addEntity(entity, transform);   
374}
375//------------------------------------------------------------------------------------------------
376StaticMeshToShapeConverter::StaticMeshToShapeConverter(Renderable *rend, const Matrix4 &transform) :
377        VertexIndexToShape(transform),
378        mEntity (0),
379        mNode (0)
380{
381        RenderOperation op;
382        rend->getRenderOperation(op);
383        VertexIndexToShape::addStaticVertexData(op.vertexData);
384        if(op.useIndexes)
385                VertexIndexToShape::addIndexData(op.indexData);
386
387}
388//------------------------------------------------------------------------------------------------
389void StaticMeshToShapeConverter::addEntity(Entity *entity,const Matrix4 &transform)
390{
391        // Each entity added need to reset size and radius
392        // next time getRadius and getSize are asked, they're computed.
393        mBounds  = Ogre::Vector3(-1,-1,-1);
394        mBoundRadius = -1;
395
396        mEntity = entity;
397        mNode = (SceneNode*)(mEntity->getParentNode());
398        mTransform = transform;
399
400        if (mEntity->getMesh()->sharedVertexData)
401        {
402                VertexIndexToShape::addStaticVertexData (mEntity->getMesh()->sharedVertexData);
403        }
404
405        for (unsigned int i = 0;i < mEntity->getNumSubEntities();++i)
406        {
407                SubMesh *sub_mesh = mEntity->getSubEntity(i)->getSubMesh();
408
409                if (!sub_mesh->useSharedVertices)
410                {
411                        VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount);
412                        VertexIndexToShape::addStaticVertexData (sub_mesh->vertexData);
413                }
414                else 
415                {
416                        VertexIndexToShape::addIndexData (sub_mesh->indexData);
417                }
418
419        }
420}
421//------------------------------------------------------------------------------------------------
422void StaticMeshToShapeConverter::addMesh(const MeshPtr &mesh, const Matrix4 &transform)
423{
424        // Each entity added need to reset size and radius
425        // next time getRadius and getSize are asked, they're computed.
426        mBounds  = Ogre::Vector3(-1,-1,-1);
427        mBoundRadius = -1;
428
429        //_entity = entity;
430        //_node = (SceneNode*)(_entity->getParentNode());
431        mTransform = transform;
432
433        if (mesh->hasSkeleton ())
434                Ogre::LogManager::getSingleton().logMessage("MeshToShapeConverter::addMesh : Mesh " + mesh->getName () + " as skeleton but added to trimesh non animated");
435
436        if (mesh->sharedVertexData)
437        {
438                VertexIndexToShape::addStaticVertexData (mesh->sharedVertexData);
439        }
440
441        for(unsigned int i = 0;i < mesh->getNumSubMeshes();++i)
442        {
443                SubMesh *sub_mesh = mesh->getSubMesh(i);
444
445                if (!sub_mesh->useSharedVertices)
446                {
447                        VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount);
448                        VertexIndexToShape::addStaticVertexData (sub_mesh->vertexData);
449                }
450                else 
451                {
452                        VertexIndexToShape::addIndexData (sub_mesh->indexData);
453                }
454
455        }
456}
457//------------------------------------------------------------------------------------------------
458AnimatedMeshToShapeConverter::AnimatedMeshToShapeConverter(Entity *entity,const Matrix4 &transform) :
459VertexIndexToShape(transform),
460mEntity (0),
461mNode (0),
462mTransformedVerticesTemp(0),
463mTransformedVerticesTempSize(0)
464{
465        addEntity(entity, transform);   
466}
467//------------------------------------------------------------------------------------------------
468AnimatedMeshToShapeConverter::AnimatedMeshToShapeConverter() :
469VertexIndexToShape(),
470mEntity (0),
471mNode (0),
472mTransformedVerticesTemp(0),
473mTransformedVerticesTempSize(0)
474{
475}
476//------------------------------------------------------------------------------------------------
477AnimatedMeshToShapeConverter::~AnimatedMeshToShapeConverter()
478{
479        delete[] mTransformedVerticesTemp;
480}
481//------------------------------------------------------------------------------------------------
482void AnimatedMeshToShapeConverter::addEntity(Entity *entity,const Matrix4 &transform)
483{
484        // Each entity added need to reset size and radius
485        // next time getRadius and getSize are asked, they're computed.
486        mBounds  = Ogre::Vector3(-1,-1,-1);
487        mBoundRadius = -1;
488
489        mEntity = entity;
490        mNode = (SceneNode*)(mEntity->getParentNode());
491        mTransform = transform;
492
493        assert (entity->getMesh()->hasSkeleton ());
494
495        mEntity->addSoftwareAnimationRequest(false);
496        mEntity->_updateAnimation();
497
498        if (mEntity->getMesh()->sharedVertexData)
499        {
500                VertexIndexToShape::addAnimatedVertexData (mEntity->getMesh()->sharedVertexData, 
501                        mEntity->_getSkelAnimVertexData(),
502                        &mEntity->getMesh()->sharedBlendIndexToBoneIndexMap); 
503        }
504
505        for (unsigned int i = 0;i < mEntity->getNumSubEntities();++i)
506        {
507                SubMesh *sub_mesh = mEntity->getSubEntity(i)->getSubMesh();
508
509                if (!sub_mesh->useSharedVertices)
510                {
511                        VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount);
512
513                        VertexIndexToShape::addAnimatedVertexData (sub_mesh->vertexData, 
514                                mEntity->getSubEntity(i)->_getSkelAnimVertexData(),
515                                &sub_mesh->blendIndexToBoneIndexMap); 
516                }
517                else 
518                {
519                        VertexIndexToShape::addIndexData (sub_mesh->indexData);
520                }
521
522        }
523
524        mEntity->removeSoftwareAnimationRequest(false);
525}
526//------------------------------------------------------------------------------------------------
527void AnimatedMeshToShapeConverter::addMesh(const MeshPtr &mesh, const Matrix4 &transform)
528{
529        // Each entity added need to reset size and radius
530        // next time getRadius and getSize are asked, they're computed.
531        mBounds  = Ogre::Vector3(-1,-1,-1);
532        mBoundRadius = -1;
533
534        //_entity = entity;
535        //_node = (SceneNode*)(_entity->getParentNode());
536        mTransform = transform;
537
538        assert (mesh->hasSkeleton ());
539
540        if (mesh->sharedVertexData)
541        {
542                VertexIndexToShape::addAnimatedVertexData (mesh->sharedVertexData, 
543                        0,
544                        &mesh->sharedBlendIndexToBoneIndexMap); 
545        }
546
547        for(unsigned int i = 0;i < mesh->getNumSubMeshes();++i)
548        {
549                SubMesh *sub_mesh = mesh->getSubMesh(i);
550
551                if (!sub_mesh->useSharedVertices)
552                {
553                        VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount);
554
555                        VertexIndexToShape::addAnimatedVertexData (sub_mesh->vertexData, 
556                                0,
557                                &sub_mesh->blendIndexToBoneIndexMap); 
558                }
559                else 
560                {
561                        VertexIndexToShape::addIndexData (sub_mesh->indexData);
562                }
563
564        }
565}
566//------------------------------------------------------------------------------------------------
567bool AnimatedMeshToShapeConverter::getBoneVertices(unsigned char bone, 
568                                                                                                         unsigned int &vertex_count, 
569                                                                                                         Ogre::Vector3* &vertices,
570                                                                                                         const Vector3 &bonePosition)
571{
572        BoneIndex::iterator i = mBoneIndex->find(bone);
573
574        if (i == mBoneIndex->end()) 
575                return false;
576
577        if (i->second->empty()) 
578                return false;
579
580        vertex_count = (unsigned int) i->second->size() + 1;
581        if (vertex_count > mTransformedVerticesTempSize)
582        {       
583                if (mTransformedVerticesTemp)
584                        delete[] mTransformedVerticesTemp;
585
586                mTransformedVerticesTemp = new Ogre::Vector3[vertex_count];
587
588        }
589
590        vertices = mTransformedVerticesTemp;
591        vertices[0] = bonePosition;
592        //mEntity->_getParentNodeFullTransform() *
593        //      mEntity->getSkeleton()->getBone(bone)->_getDerivedPosition();
594
595        //mEntity->getSkeleton()->getBone(bone)->_getDerivedOrientation()
596        unsigned int currBoneVertex = 1;
597        Vector3Array::iterator j = i->second->begin();
598        while(j != i->second->end())
599        {
600                vertices[currBoneVertex] = (*j);
601                ++j;
602                ++currBoneVertex; 
603        }       
604        return true;
605}
606//------------------------------------------------------------------------------------------------
607BoxCollisionShape* AnimatedMeshToShapeConverter::createAlignedBox(unsigned char bone, 
608                                                                                                                                  const Vector3 &bonePosition,
609                                                                                                                                  const Quaternion &boneOrientation)
610{
611        unsigned int vertex_count;
612        Vector3* vertices;
613
614        if (!getBoneVertices(bone, vertex_count, vertices, bonePosition)) 
615                return 0;
616
617        Vector3 min_vec(vertices[0]);
618        Vector3 max_vec(vertices[0]);
619
620        for(unsigned int j = 1; j < vertex_count ;j++)
621        {
622                min_vec.x = std::min(min_vec.x,vertices[j].x);
623                min_vec.y = std::min(min_vec.y,vertices[j].y);
624                min_vec.z = std::min(min_vec.z,vertices[j].z);
625
626                max_vec.x = std::max(max_vec.x,vertices[j].x);
627                max_vec.y = std::max(max_vec.y,vertices[j].y);
628                max_vec.z = std::max(max_vec.z,vertices[j].z);
629        }
630        const Ogre::Vector3 maxMinusMin(max_vec - min_vec);
631        BoxCollisionShape* box = new BoxCollisionShape(maxMinusMin);
632
633        const Ogre::Vector3 pos
634                (min_vec.x + (maxMinusMin.x * 0.5),
635                min_vec.y + (maxMinusMin.y * 0.5),
636                min_vec.z + (maxMinusMin.z * 0.5));
637
638        //box->setPosition(pos);
639
640        return box;
641}
642//------------------------------------------------------------------------------------------------
643bool AnimatedMeshToShapeConverter::getOrientedBox(unsigned char bone, 
644                                         const Vector3 &bonePosition,
645                                         const Quaternion &boneOrientation,
646                                         Vector3 &box_afExtent,
647                                         Vector3 *box_akAxis,
648                                         Vector3 &box_kCenter)
649{
650        unsigned int vertex_count;
651        Vector3* vertices;
652
653        if (!getBoneVertices(bone, vertex_count, vertices, bonePosition))
654                return false;
655
656         box_kCenter = Vector3::ZERO;
657
658         {
659                 for(unsigned int c = 0 ;c < vertex_count;c++)
660                 {
661                         box_kCenter += vertices[c];
662                 }
663                 const Ogre::Real invVertexCount = 1.0 / vertex_count;
664                 box_kCenter *= invVertexCount;
665         }
666        Quaternion orient = boneOrientation;
667        orient.ToAxes(box_akAxis);
668
669
670        // Let C be the box center and let U0, U1, and U2 be the box axes.  Each
671        // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
672        // following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
673        // and max(y2).  The box center is then adjusted to be
674        //   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
675        //        0.5*(min(y2)+max(y2))*U2
676
677        Ogre::Vector3 kDiff (vertices[1] - box_kCenter);
678        Ogre::Real fY0Min = kDiff.dotProduct(box_akAxis[0]), fY0Max = fY0Min;
679        Ogre::Real fY1Min = kDiff.dotProduct(box_akAxis[1]), fY1Max = fY1Min;
680        Ogre::Real fY2Min = kDiff.dotProduct(box_akAxis[2]), fY2Max = fY2Min;
681
682        for (unsigned int i = 2; i < vertex_count; i++)
683        {
684                kDiff = vertices[i] - box_kCenter;
685
686                const Ogre::Real fY0 = kDiff.dotProduct(box_akAxis[0]);
687                if ( fY0 < fY0Min )
688                        fY0Min = fY0;
689                else if ( fY0 > fY0Max )
690                        fY0Max = fY0;
691
692                const Ogre::Real fY1 = kDiff.dotProduct(box_akAxis[1]);
693                if ( fY1 < fY1Min )
694                        fY1Min = fY1;
695                else if ( fY1 > fY1Max )
696                        fY1Max = fY1;
697
698                const Ogre::Real fY2 = kDiff.dotProduct(box_akAxis[2]);
699                if ( fY2 < fY2Min )
700                        fY2Min = fY2;
701                else if ( fY2 > fY2Max )
702                        fY2Max = fY2;
703        }
704
705        box_afExtent.x = ((Real)0.5)*(fY0Max - fY0Min);
706        box_afExtent.y = ((Real)0.5)*(fY1Max - fY1Min);
707        box_afExtent.z = ((Real)0.5)*(fY2Max - fY2Min);
708
709        box_kCenter += (0.5*(fY0Max+fY0Min))*box_akAxis[0] +
710                (0.5*(fY1Max+fY1Min))*box_akAxis[1] +
711                (0.5*(fY2Max+fY2Min))*box_akAxis[2];
712
713        box_afExtent *= 2.0;
714
715        return true;
716}
717//------------------------------------------------------------------------------------------------
718BoxCollisionShape* AnimatedMeshToShapeConverter::createOrientedBox(unsigned char bone, 
719                                                                                                                                   const Vector3 &bonePosition,
720                                                                                                                                   const Quaternion &boneOrientation)
721{
722        Ogre::Vector3 box_akAxis[3];
723        Ogre::Vector3 box_afExtent;
724        Ogre::Vector3 box_afCenter;
725
726        if (!getOrientedBox(bone, bonePosition, boneOrientation,
727                                                box_afExtent,
728                                                box_akAxis,
729                                                box_afCenter))
730                return 0;
731
732        BoxCollisionShape *geom = new BoxCollisionShape(box_afExtent);
733        //geom->setOrientation(Quaternion(box_akAxis[0],box_akAxis[1],box_akAxis[2]));
734        //geom->setPosition(box_afCenter);
735        return geom; 
736}
737//------------------------------------------------------------------------------------------------
738CapsuleCollisionShape* AnimatedMeshToShapeConverter::createOrientedCapsuleCollisionShape(unsigned char bone, 
739                                                                                                                                                                                         const Vector3 &bonePosition,
740                                                                                                                                                                                         const Quaternion &boneOrientation)
741{
742        Ogre::Vector3 box_akAxis[3];
743        Ogre::Vector3 box_afExtent;
744        Ogre::Vector3 box_afCenter;
745
746        if (!getOrientedBox(bone,  bonePosition, boneOrientation,
747                                                box_afExtent,
748                                                box_akAxis,
749                                                box_afCenter))
750                return 0;
751
752        // find axes with longest length
753
754        Vector3 cap_dir;    //std::max(box_afExtent.x,std::max(box_afExtent.y,box_afExtent.z));
755        Real cap_dirLength;  //std::max(box_afExtent.x,std::max(box_afExtent.y,box_afExtent.z));
756        Real cap_radius;         // max axe length
757        if (box_afExtent.x - box_afExtent.y > 0 && box_afExtent.x - box_afExtent.z > 0)
758        {
759                cap_dir = Vector3::UNIT_X;
760                cap_dirLength = box_afExtent.x;
761                cap_radius = std::max (box_afExtent.y, box_afExtent.z);
762        }
763        else if (box_afExtent.y - box_afExtent.x > 0 && box_afExtent.y - box_afExtent.z > 0)
764        {
765                cap_dir = Vector3::UNIT_Y;
766                cap_dirLength = box_afExtent.y;
767                cap_radius = std::max (box_afExtent.x, box_afExtent.z);
768        }
769        else if (box_afExtent.z - box_afExtent.y > 0 && box_afExtent.z - box_afExtent.y > 0)
770        {
771                cap_dir = Vector3::UNIT_Z;
772                cap_dirLength = box_afExtent.z;
773                cap_radius = std::max (box_afExtent.x, box_afExtent.z);
774        }
775
776        CapsuleCollisionShape* geom = new CapsuleCollisionShape(cap_radius, cap_dirLength, cap_dir);
777
778        //geom->setOrientation(orient);
779        //geom->setPosition(cap_orig + (boneOrientation * (cap_dirLength * 0.5)));
780
781        return geom;
782}
Note: See TracBrowser for help on using the repository browser.