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

Revision 2614, 20.2 KB checked in by mattausch, 16 years ago (diff)

worked on dynamic objects

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