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

Revision 1867, 20.0 KB checked in by bittner, 18 years ago (diff)

merge, global lines, rss sampling updates

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