source: GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp @ 2176

Revision 2176, 19.9 KB checked in by mattausch, 17 years ago (diff)

removed using namespace std from .h

Line 
1#include "Ray.h"
2#include "Mesh.h"
3#include "MeshKdTree.h"
4#include "Triangle3.h"
5#include "ResourceManager.h"
6
7using namespace std;
8
9namespace GtpVisibilityPreprocessor {
10
11bool MeshDebug = false;
12
13  //int Intersectable::sMailId = 1;//2147483647;
14  //int Intersectable::sReservedMailboxes = 1;
15
16struct SortableVertex {
17
18  Vector3 vertex;
19
20  int originalId;
21  int newId;
22  int finalPos;
23
24  SortableVertex() {}
25
26  SortableVertex(const Vector3 &v,
27                                 const int id):
28        vertex(v),
29        originalId(id),
30        newId(id)
31  {}
32 
33  friend bool operator<(const SortableVertex &a,
34                                                const SortableVertex &b)
35  {
36        if (a.vertex.x < b.vertex.x)
37          return true;
38        else
39          if (a.vertex.x > b.vertex.x)
40                return false;
41       
42        if (a.vertex.y < b.vertex.y)
43          return true;
44        else
45          if (a.vertex.y > b.vertex.y)
46                return false;
47       
48        if (a.vertex.z < b.vertex.z)
49          return true;
50        else
51          //      if (a.z > b.z)
52          return false;
53       
54        //      return false;
55  }
56
57};
58
59
60void
61Mesh::ComputeBoundingBox()
62{
63
64  mBox.Initialize();
65  VertexContainer::const_iterator vi = mVertices.begin();
66  for (; vi != mVertices.end(); vi++) {
67    mBox.Include(*vi);
68  }
69//mBox.Enlarge(1e-4f);
70}
71
72void
73Mesh::Preprocess(bool cleanup)
74{
75  if (cleanup)
76        Cleanup();
77 
78        ComputeBoundingBox();
79 
80        /** true if it is a watertight convex mesh
81        */
82        mIsConvex = false;
83
84        if (mFaces.size() > MeshKdTree::mTermMinCost)
85        {
86                mKdTree = new MeshKdTree(this);
87                MeshKdLeaf *root = (MeshKdLeaf *)mKdTree->GetRoot();
88               
89                for (int i = 0; i < mFaces.size(); i++)
90                        root->mFaces.push_back(i);
91               
92                cout<<"KD";
93               
94                mKdTree->Construct();
95
96                if (mKdTree->GetRoot()->IsLeaf())
97                {
98                        cout<<"d";
99                        delete mKdTree;
100                        mKdTree = NULL;
101                }
102        }
103}
104
105
106void
107Mesh::IndexVertices()
108{
109  int i;
110  // check whether the vertices can be simplfied and reindexed
111  vector<SortableVertex> svertices(mVertices.size());
112
113  for (i=0; i < mVertices.size(); i++)
114        svertices[i] = SortableVertex(mVertices[i], i);
115
116  sort(svertices.begin(), svertices.end());
117
118  for (i=0; i < svertices.size() - 1; i++)
119        if (svertices[i].vertex == svertices[i+1].vertex)
120          svertices[i+1].newId = svertices[i].newId;
121
122  // remove the same vertices
123  int k = 0;
124  mVertices[0] = svertices[0].vertex;
125  svertices[0].finalPos = 0;
126 
127  for (i=1; i < svertices.size(); i++) {
128        if (svertices[i].newId != svertices[i-1].newId)
129          k++;
130       
131        mVertices[k] = svertices[i].vertex;
132        svertices[i].finalPos = k;
133  }
134
135  mVertices.resize(k + 1);
136 
137  vector<int> remapBuffer(svertices.size());
138  for (i = 0; i < svertices.size(); i++)
139        remapBuffer[svertices[i].originalId] = svertices[i].finalPos;
140 
141  // remap all faces
142 
143  for (int faceIndex = 0; faceIndex < mFaces.size(); faceIndex++) {
144        Face *face = mFaces[faceIndex];
145        for (int i = 0; i < face->mVertexIndices.size(); i++) {
146          face->mVertexIndices[i] = remapBuffer[face->mVertexIndices[i]];
147        }
148  }
149}
150
151AxisAlignedBox3
152Mesh::GetFaceBox(const int faceIndex)
153{
154  Face *face = mFaces[faceIndex];
155  AxisAlignedBox3 box;
156  box.SetMin( mVertices[face->mVertexIndices[0]] );
157  box.SetMax(box.Min());
158  for (int i = 1; i < face->mVertexIndices.size(); i++) {
159    box.Include(mVertices[face->mVertexIndices[i]]);
160  }
161  return box;
162}
163
164int
165Mesh::CastRayToFace(
166                                        const int faceIndex,
167                                        Ray &ray,
168                                        float &nearestT,
169                                        Vector3 &nearestNormal,
170                                        int &nearestFace,
171                                        Intersectable *instance
172                                        )
173{
174  float t;
175  int hit = 0;
176  Vector3 normal;
177  if (RayFaceIntersection(faceIndex, ray, t, normal, nearestT) == Ray::INTERSECTION) {
178    switch (ray.GetType()) {
179    case Ray::GLOBAL_RAY:
180      ray.intersections.push_back(Ray::Intersection(t, normal, instance, faceIndex));
181      hit++;
182      break;
183    case Ray::LOCAL_RAY:
184      nearestT = t;
185          nearestNormal = normal;
186      nearestFace = faceIndex;
187      hit++;
188      break;
189    case Ray::LINE_SEGMENT:
190      if (t <= 1.0f) {
191                ray.intersections.push_back(Ray::Intersection(t, normal, instance, faceIndex));
192                hit++;
193      }
194      break;
195    }
196  }
197  return hit;
198}
199
200int
201Mesh::CastRay(
202                          Ray &ray,
203                          MeshInstance *instance
204                          )
205{
206  if (mKdTree) {
207    return mKdTree->CastRay(ray, instance);
208  }
209 
210  int faceIndex = 0;
211  int hits = 0;
212  float nearestT = MAX_FLOAT;
213  Vector3 nearestNormal;
214  int nearestFace = -1;
215 
216  if (ray.GetType() == Ray::LOCAL_RAY && !ray.intersections.empty())
217    nearestT = ray.intersections[0].mT;
218
219       
220  for ( ;
221                faceIndex < mFaces.size();
222                faceIndex++) {
223    hits += CastRayToFace(faceIndex,
224                                                  ray,
225                                                  nearestT,
226                                                  nearestNormal,
227                                                  nearestFace,
228                                                  instance);
229    if (mIsConvex && nearestFace != -1)
230      break;
231  }
232 
233  if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
234    if (!ray.intersections.empty())
235      ray.intersections[0] = Ray::Intersection(nearestT,
236                                                                                           nearestNormal,
237                                                                                           instance,
238                                                                                           nearestFace);
239    else
240      ray.intersections.push_back(Ray::Intersection(nearestT,
241                                                                                                        nearestNormal,
242                                                                                                        instance,
243                                                                                                        nearestFace));
244  }
245 
246  return hits;
247}
248
249int
250Mesh::CastRayToSelectedFaces(
251                                                         Ray &ray,
252                                                         const vector<int> &faces,
253                                                         Intersectable *instance
254                                                         )
255{
256  vector<int>::const_iterator fi;
257  int faceIndex = 0;
258  int hits = 0;
259  float nearestT = MAX_FLOAT;
260  Vector3 nearestNormal;
261  int nearestFace = -1;
262 
263  if (ray.GetType() == Ray::LOCAL_RAY && ray.intersections.size())
264    nearestT = ray.intersections[0].mT;
265
266  for ( fi = faces.begin();
267                fi != faces.end();
268                fi++) {
269    hits += CastRayToFace(*fi, ray, nearestT, nearestNormal, nearestFace, instance);
270    if (mIsConvex && nearestFace != -1)
271      break;
272  }
273 
274  if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
275    if (ray.intersections.size())
276      ray.intersections[0] = Ray::Intersection(nearestT, nearestNormal,instance, nearestFace);
277    else
278      ray.intersections.push_back(Ray::Intersection(nearestT, nearestNormal,instance, nearestFace));
279  }
280 
281  return hits;
282}
283
284
285// int_lineseg returns 1 if the given line segment intersects a 2D
286// ray travelling in the positive X direction.  This is used in the
287// Jordan curve computation for polygon intersection.
288inline int
289int_lineseg(float px,
290                        float py,
291                        float u1,
292                        float v1,
293                        float u2,
294                        float v2)
295{
296  float ydiff;
297
298  u1 -= px; u2 -= px;     // translate line
299  v1 -= py; v2 -= py;
300
301  if ((v1 > 0 && v2 > 0) ||
302      (v1 < 0 && v2 < 0) ||
303      (u1 < 0 && u2 < 0))
304    return 0;
305
306  if (u1 > 0 && u2 > 0)
307    return 1;
308
309  ydiff = v2 - v1;
310  if (fabs(ydiff) < Limits::Small) {      // denominator near 0
311    if (((fabs(v1) > Limits::Small) ||
312                 (u1 > 0) || (u2 > 0)))
313      return 0;
314    return 1;
315  }
316 
317  double t = -v1 / ydiff;                 // Compute parameter
318
319  double thresh;
320
321  if (ydiff < 0.0f)
322        thresh = -1e-20;
323  else
324        thresh = 1e-20;
325
326 
327  return (u1 + t * (u2 - u1)) > thresh; //-Limits::Small;
328}
329
330
331
332// intersection with the polygonal face of the mesh
333int
334Mesh::RayFaceIntersection(const int faceIndex,
335                                                  const Ray &ray,
336                                                  float &t,
337                                                  Vector3 &normal,
338                                                  const float nearestT
339                                                  )
340{
341  Face *face  = mFaces[faceIndex];
342
343  Plane3 plane = GetFacePlane(faceIndex);
344  float dot = DotProd(plane.mNormal, ray.GetDir());
345
346  if (MeshDebug) {
347        cout<<endl<<endl;
348        cout<<"normal="<<plane.mNormal<<endl;
349        cout<<"dot="<<dot<<endl;
350  }
351 
352       
353  // Watch for near-zero denominator
354  // ONLY single sided polygons!!!!!
355  if (ray.mFlags & Ray::CULL_BACKFACES) {
356        if (dot > -Limits::Small)
357          //  if (fabs(dot) < Limits::Small)
358          return Ray::NO_INTERSECTION;
359  } else {
360        if (fabs(dot) < Limits::Small)
361          return Ray::NO_INTERSECTION;
362  }
363 
364  normal = plane.mNormal;
365
366  t = (-plane.mD - DotProd(plane.mNormal, ray.GetLoc())) / dot;
367
368  if (MeshDebug)
369        cout<<"t="<<t<<endl;
370
371  if (t <= Limits::Small)
372    return Ray::INTERSECTION_OUT_OF_LIMITS;
373 
374  if ((ray.GetType() == Ray::LOCAL_RAY) && (t >= nearestT)) {
375    return Ray::INTERSECTION_OUT_OF_LIMITS; // no intersection was found
376  }
377 
378  int count = 0;
379  float u, v, u1, v1, u2, v2;
380  int i;
381
382  int paxis = plane.mNormal.DrivingAxis();
383
384 
385  // Project the intersection point onto the coordinate plane
386  // specified by which.
387  ray.Extrap(t).ExtractVerts(&u, &v, paxis);
388
389
390  int size = (int)face->mVertexIndices.size();
391
392  if (MeshDebug)
393        cout<<"size="<<size<<endl;
394 
395  mVertices[face->mVertexIndices[size - 1]].
396    ExtractVerts(&u1, &v1, paxis );
397 
398  //$$JB changed 12.4.2006 from 0 ^^
399  if (0 && size <= 4) {
400    // assume a convex face
401    for (i = 0; i < size; i++) {
402      mVertices[face->mVertexIndices[i]].ExtractVerts(&u2, &v2, paxis);
403      // line u1, v1, u2, v2
404      if ((v1 - v2)*(u - u1) + (u2 - u1)*(v - v1) > 0) {
405                if (MeshDebug)
406                  cout<<"exit on "<<i<<endl;
407                return Ray::NO_INTERSECTION;
408          }
409      u1 = u2;
410      v1 = v2;
411    }
412   
413    return Ray::INTERSECTION;
414  }
415 
416  // We're stuck with the Jordan curve computation.  Count number
417  // of intersections between the line segments the polygon comprises
418  // with a ray originating at the point of intersection and
419  // travelling in the positive X direction.
420  for (i = 0; i < size; i++) {
421    mVertices[face->mVertexIndices[i]].ExtractVerts(&u2, &v2, paxis);
422    count += (int_lineseg(u, v, u1, v1, u2, v2) != 0);
423    u1 = u2;
424    v1 = v2;
425  }
426
427  if (MeshDebug)
428        cout<<"count="<<count<<endl;
429
430  // We hit polygon if number of intersections is odd.
431  return (count & 1) ? Ray::INTERSECTION : Ray::NO_INTERSECTION;
432}
433
434int
435Mesh::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal)
436{
437        //const int faceIndex = (int)RandomValue(0, (Real)((int)mFaces.size()-1));
438        const int faceIndex = (int)RandomValue(0, (Real)mFaces.size() - 0.5f);
439
440        // assume the face is convex and generate a convex combination
441        Face *face = mFaces[faceIndex];
442
443        point = Vector3(0,0,0);
444        float sum = 0.0f;
445
446        for (int i = 0; i < face->mVertexIndices.size(); i++) {
447                float r = RandomValue(0,1);
448                sum += r;
449                point += mVertices[face->mVertexIndices[i]]*r;
450        }
451        point *= 1.0f/sum;
452
453        normal = GetFacePlane(faceIndex).mNormal;
454
455        return faceIndex;
456}
457
458int
459Mesh::GetRandomVisibleSurfacePoint(Vector3 &point,
460                                                                   Vector3 &normal,
461                                                                   const Vector3 &viewpoint,
462                                                                   const int maxTries)
463{
464  Plane3 plane;
465  const int faceIndex = (int)RandomValue(0, (Real)mFaces.size() - 0.5f);
466        int tries;
467  for (tries = 0; tries < maxTries; tries++) {
468    Face *face = mFaces[faceIndex];
469    plane = GetFacePlane(faceIndex);
470   
471    if (plane.Side(viewpoint) > 0) {
472      point = Vector3(0,0,0);
473      float sum = 0.0f;
474      // pickup a point inside this triangle
475      for (int i = 0; i < face->mVertexIndices.size(); i++) {
476                                float r = RandomValue(0,1);
477                                sum += r;
478                                point += mVertices[face->mVertexIndices[i]]*r;
479      }
480      point *= 1.0f/sum;
481      break;
482    }
483  }
484 
485  normal = plane.mNormal;
486  return (tries < maxTries) ? faceIndex + 1 : 0;
487}
488
489
490Plane3
491Mesh::GetFacePlane(const int faceIndex) const
492{
493  Face *face = mFaces[faceIndex];
494        return Plane3(mVertices[face->mVertexIndices[0]],
495                                                                mVertices[face->mVertexIndices[1]],
496                                                                mVertices[face->mVertexIndices[2]]);
497}
498
499bool
500Mesh::ValidateFace(const int i)
501{
502        Face *face = mFaces[i];
503
504        Plane3 plane = Plane3(mVertices[face->mVertexIndices[0]],
505                                                  mVertices[face->mVertexIndices[1]],
506                                                  mVertices[face->mVertexIndices[2]]);
507       
508        if (!eq(Magnitude(plane.mNormal), 1.0f))
509                return false;
510
511        return true;
512}
513
514
515bool Mesh::CheckMesh() const
516{
517        VertexContainer::const_iterator vit, vit_end = mVertices.end();
518
519        for (vit = mVertices.begin(); vit != vit_end; ++ vit)
520        {
521                for (int i = 0; i < 3; ++ i)
522                {
523                        const float x = (*vit)[i];
524                        if (x != x) // nan
525                        //if (isnan((*vit)[i]))
526                        {
527                                cout << "warning: vertex is ill defined" << endl;
528                                return false;
529                        }
530                }
531        }
532        return true;
533}
534
535
536static void PrintFace(const Mesh *mesh, const int idx, ostream &app)
537{
538        Face *face = mesh->mFaces[idx];
539
540        VertexIndexContainer::iterator it, it_end = face->mVertexIndices.end();
541
542        cout << "face " << idx << endl;
543        for (it = face->mVertexIndices.begin(); it != it_end; ++ it)
544        {
545                cout << (*it) << ": " << mesh->mVertices[*it] << " ";
546        }
547        cout << endl;
548}
549
550
551void Mesh::Print(ostream &app) const
552{
553        VertexContainer::const_iterator vit, vit_end = mVertices.end();
554
555        for (vit = mVertices.begin(); vit != vit_end; ++ vit)
556        {
557                app << (*vit) << " ";
558        }
559        app << endl;
560
561        for (int i = 0; i < (int)mFaces.size(); ++ i)
562        {
563                PrintFace(this, i, app);
564        }
565}
566
567
568void
569Mesh::Cleanup()
570{
571        int toRemove = 0;
572        FaceContainer newFaces;
573        for (int i=0; i < mFaces.size(); i++)
574                if (ValidateFace(i)) {
575                        newFaces.push_back(mFaces[i]);
576                } else {
577                        cout<<"d";
578                        delete mFaces[i];
579                        toRemove++;
580                }
581       
582        if (toRemove) {
583                mFaces = newFaces;
584        }
585       
586        // cleanup vertices??
587}
588
589
590Vector3 Mesh::GetNormal(const int idx) const
591{
592        return GetFacePlane(idx).mNormal;
593}
594
595
596void
597Mesh::AddTriangle(const Triangle3 &triangle)
598{
599  int index = (int)mVertices.size();
600
601  for (int i=0; i < 3; i++) {
602    mVertices.push_back(triangle.mVertices[i]);
603  }
604 
605  AddFace(new Face(index + 0, index + 1, index + 2) );
606}
607
608void
609Mesh::AddRectangle(const Rectangle3 &rect)
610{
611  int index = (int)mVertices.size();
612
613  for (int i=0; i < 4; i++) {
614    mVertices.push_back(rect.mVertices[i]);
615  }
616 
617  AddFace(new Face(index + 0, index + 1, index + 2, index + 3) );
618}
619
620void
621Mesh::AssignRandomMaterial()
622
623        mMaterial = MaterialManager::GetSingleton()->CreateResource();
624 
625        Material randMat = RandomMaterial();
626
627        mMaterial->mDiffuseColor = randMat.mDiffuseColor;
628        mMaterial->mSpecularColor = randMat.mSpecularColor;
629        mMaterial->mAmbientColor = randMat.mAmbientColor;
630}
631
632
633Mesh *CreateMeshFromBox(const AxisAlignedBox3 &box)
634{
635        Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
636
637        // add 8 vertices of the box
638        const int index = (int)mesh->mVertices.size();
639       
640        for (int i=0; i < 8; ++ i)
641        {
642        Vector3 v;
643                box.GetVertex(i, v);
644                mesh->mVertices.push_back(v);
645        }
646
647        mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
648        mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
649        mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
650 
651        mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
652        mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
653        mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
654 
655        return mesh;
656}
657
658
659Mesh::Mesh(const int id, const int vertices, const int faces):
660mFaces(),
661mMaterial(NULL),
662mKdTree(NULL),
663mVertices(),
664mIsConvex(false),
665mIsWatertight(false),
666mId(id)
667{
668    mVertices.reserve(vertices);
669    mFaces.reserve(faces);
670}
671
672
673Mesh::Mesh(const int id):
674mId(id), mVertices(), mFaces(), mMaterial(NULL), mKdTree(NULL)
675{}
676
677
678// apply transformation to each vertex
679void Mesh::ApplyTransformation(const Matrix4x4 &m)
680{
681        VertexContainer::iterator it, it_end = mVertices.end();
682
683        for (it = mVertices.begin(); it != it_end; ++ it)
684        {
685                (*it) = m * (*it);       
686        }
687}
688
689
690Mesh::Mesh(const Mesh &rhs):
691mKdTree(NULL)
692{
693        mVertices = rhs.mVertices;
694        mFaces.reserve(rhs.mFaces.size());
695        mId = rhs.mId;
696        mMaterial = rhs.mMaterial;
697       
698        FaceContainer::const_iterator it, it_end = rhs.mFaces.end();
699
700        for (it = rhs.mFaces.begin(); it != it_end; ++ it)
701        {
702                Face *face = *it;
703                mFaces.push_back(new Face(*face));
704        }
705}
706
707
708Mesh& Mesh::operator=(const Mesh& m)
709{
710    if (this == &m)
711                return *this;
712 
713        CLEAR_CONTAINER(mFaces);
714
715        mVertices = m.mVertices;
716        mFaces.reserve(m.mFaces.size());
717        mMaterial = m.mMaterial;
718        // note: we don't copy id on purpose
719        //mId = m.mId;
720       
721        FaceContainer::const_iterator it, it_end = m.mFaces.end();
722
723        for (it = m.mFaces.begin(); it != it_end; ++ it)
724        {
725                Face *face = *it;
726                mFaces.push_back(new Face(*face));
727        }
728
729        return *this;
730}
731
732
733Mesh::~Mesh()
734{
735        for (int i=0; i < mFaces.size(); ++ i)
736                delete mFaces[i];
737
738        DEL_PTR(mKdTree);
739}
740 
741
742void Mesh::Clear()
743{
744        mVertices.clear();
745        mFaces.clear();
746
747        DEL_PTR(mKdTree);
748}
749
750
751
752/********************************************************/
753/*                      MeshInstance implementation             */
754/********************************************************/
755
756int
757MeshInstance::CastRay(
758                                          Ray &ray
759                                          )
760{
761  int res = mMesh->CastRay(ray, this);
762
763  return res;
764}
765
766int
767MeshInstance::CastRay(
768                                          Ray &ray,
769                                          const vector<int> &faces
770                                          )
771{
772  return mMesh->CastRayToSelectedFaces(ray, faces, this);
773}
774
775
776
777int
778MeshInstance::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal)
779{
780  return mMesh->GetRandomSurfacePoint(point, normal);
781}
782
783int
784MeshInstance::GetRandomVisibleSurfacePoint(Vector3 &point,
785                                                                                   Vector3 &normal,
786                                                                                   const Vector3 &viewpoint,
787                                                                                   const int maxTries)
788{
789        return mMesh->GetRandomVisibleSurfacePoint(point, normal, viewpoint, maxTries);
790}
791
792
793void MeshInstance::SetMaterial(Material *mat)
794{
795        mMaterial = mat;
796}
797
798Material *MeshInstance::GetMaterial() const
799{
800        return mMaterial;
801}
802
803
804Vector3 MeshInstance::GetNormal(const int idx) const
805{
806        return mMesh->GetNormal(idx);
807}
808
809
810int MeshInstance::GetRandomEdgePoint(Vector3 &point, Vector3 &normal)
811{
812        // get random face
813        const int faceIdx = (int)RandomValue(0.0f, (float)mMesh->mFaces.size() - 0.5f);
814        Face *face = mMesh->mFaces[faceIdx];
815
816        // get random edge of face (hack: this is not uniform in the edges!
817        const int edgeIdx = (int)RandomValue(0.0f, (float)face->mVertexIndices.size() - 0.5f);
818
819        //cout << "idx = " << edgeIdx << " s: " << face->mVertexIndices.size() << endl;
820        const int vertexIdxA = face->mVertexIndices[edgeIdx];
821        const int vertexIdxB = face->mVertexIndices[(edgeIdx + 1) % (int)face->mVertexIndices.size()];
822
823        const Vector3 a = mMesh->mVertices[vertexIdxA];
824        const Vector3 b = mMesh->mVertices[vertexIdxB];
825
826        const float w = RandomValue(0.0f, 1.0f);
827
828        // get random point on edge
829        point = a * w + b * (1.0f - w);
830
831        //cout << "va " << a << " vb " << b << "p " << point << endl;
832        // hack: set normal of face as normal
833        normal = mMesh->GetFacePlane(faceIdx).mNormal;
834
835    return 1;
836}
837
838
839/*************************************************************/
840/*           TransformedMeshInstance implementation          */
841/*************************************************************/
842
843
844TransformedMeshInstance::TransformedMeshInstance(Mesh *mesh):
845MeshInstance(mesh)
846{
847    mWorldTransform = IdentityMatrix();
848}
849
850
851int TransformedMeshInstance::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal)
852{
853  const int index = mMesh->GetRandomSurfacePoint(point, normal);
854  point = mWorldTransform * point;
855  normal = TransformNormal(mWorldTransform, normal);
856  return index;
857}
858
859
860int TransformedMeshInstance::CastRay(Ray &ray)
861{
862        ray.ApplyTransform(Invert(mWorldTransform));
863       
864        const int res = mMesh->CastRay(ray, this);
865        ray.ApplyTransform(mWorldTransform);
866
867    return res;
868}
869
870
871int TransformedMeshInstance::CastRay(Ray &ray, const vector<int> &faces)
872{
873        ray.ApplyTransform(Invert(mWorldTransform));
874
875        const int res = mMesh->CastRayToSelectedFaces(ray, faces, this);
876        ray.ApplyTransform(mWorldTransform);
877
878         return res;
879}
880
881
882void TransformedMeshInstance::ApplyWorldTransform(const Matrix4x4 &m)
883{
884        mWorldTransform = m * mWorldTransform;
885}
886
887
888void TransformedMeshInstance::LoadWorldTransform(const Matrix4x4 &m)
889{
890        mWorldTransform = m;
891}
892
893
894void TransformedMeshInstance::GetWorldTransform(Matrix4x4 &m) const
895{
896        m = mWorldTransform;
897}
898
899
900AxisAlignedBox3 TransformedMeshInstance::GetBox() const
901{
902    return Transform(mMesh->mBox, mWorldTransform);
903}
904
905
906void TransformedMeshInstance::GetTransformedMesh(Mesh &transformedMesh) const
907{
908        // copy mesh
909        transformedMesh = *mMesh;
910        transformedMesh.ApplyTransformation(mWorldTransform);
911}
912
913
914Vector3 TransformedMeshInstance::GetNormal(const int idx) const
915{
916        Mesh mesh;
917        GetTransformedMesh(mesh);
918        return mesh.GetFacePlane(idx).mNormal;
919}
920
921}
Note: See TracBrowser for help on using the repository browser.