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

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

removed using namespace std from .h

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
[162]60void
[859]61Mesh::ComputeBoundingBox()
[863]62{
63
[752]64  mBox.Initialize();
[162]65  VertexContainer::const_iterator vi = mVertices.begin();
66  for (; vi != mVertices.end(); vi++) {
[176]67    mBox.Include(*vi);
[162]68  }
[873]69//mBox.Enlarge(1e-4f);
[863]70}
71
[859]72void
[1292]73Mesh::Preprocess(bool cleanup)
[859]74{
[1292]75  if (cleanup)
[870]76        Cleanup();
[1076]77 
[870]78        ComputeBoundingBox();
[1076]79 
[870]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";
[1076]93               
[870]94                mKdTree->Construct();
95
96                if (mKdTree->GetRoot()->IsLeaf())
97                {
98                        cout<<"d";
99                        delete mKdTree;
100                        mKdTree = NULL;
101                }
102        }
[162]103}
104
[752]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
[170]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}
[162]163
164int
[170]165Mesh::CastRayToFace(
[878]166                                        const int faceIndex,
167                                        Ray &ray,
168                                        float &nearestT,
[1199]169                                        Vector3 &nearestNormal,
[878]170                                        int &nearestFace,
171                                        Intersectable *instance
172                                        )
[170]173{
174  float t;
175  int hit = 0;
[1199]176  Vector3 normal;
177  if (RayFaceIntersection(faceIndex, ray, t, normal, nearestT) == Ray::INTERSECTION) {
[170]178    switch (ray.GetType()) {
179    case Ray::GLOBAL_RAY:
[1199]180      ray.intersections.push_back(Ray::Intersection(t, normal, instance, faceIndex));
[170]181      hit++;
182      break;
183    case Ray::LOCAL_RAY:
184      nearestT = t;
[1199]185          nearestNormal = normal;
[170]186      nearestFace = faceIndex;
187      hit++;
188      break;
[245]189    case Ray::LINE_SEGMENT:
190      if (t <= 1.0f) {
[1199]191                ray.intersections.push_back(Ray::Intersection(t, normal, instance, faceIndex));
[878]192                hit++;
[245]193      }
194      break;
[170]195    }
196  }
197  return hit;
198}
199
200int
[162]201Mesh::CastRay(
[444]202                          Ray &ray,
203                          MeshInstance *instance
204                          )
[162]205{
[170]206  if (mKdTree) {
207    return mKdTree->CastRay(ray, instance);
208  }
209 
[162]210  int faceIndex = 0;
211  int hits = 0;
212  float nearestT = MAX_FLOAT;
[1199]213  Vector3 nearestNormal;
[170]214  int nearestFace = -1;
215 
[1990]216  if (ray.GetType() == Ray::LOCAL_RAY && !ray.intersections.empty())
[162]217    nearestT = ray.intersections[0].mT;
218
[376]219       
[162]220  for ( ;
[492]221                faceIndex < mFaces.size();
222                faceIndex++) {
[1824]223    hits += CastRayToFace(faceIndex,
[1981]224                                                  ray,
225                                                  nearestT,
226                                                  nearestNormal,
227                                                  nearestFace,
228                                                  instance);
[170]229    if (mIsConvex && nearestFace != -1)
230      break;
[162]231  }
232 
233  if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
[1990]234    if (!ray.intersections.empty())
[1824]235      ray.intersections[0] = Ray::Intersection(nearestT,
[1990]236                                                                                           nearestNormal,
237                                                                                           instance,
238                                                                                           nearestFace);
[162]239    else
[1824]240      ray.intersections.push_back(Ray::Intersection(nearestT,
[1990]241                                                                                                        nearestNormal,
242                                                                                                        instance,
243                                                                                                        nearestFace));
[162]244  }
245 
246  return hits;
247}
248
[170]249int
250Mesh::CastRayToSelectedFaces(
[492]251                                                         Ray &ray,
252                                                         const vector<int> &faces,
253                                                         Intersectable *instance
254                                                         )
[170]255{
256  vector<int>::const_iterator fi;
257  int faceIndex = 0;
258  int hits = 0;
259  float nearestT = MAX_FLOAT;
[1199]260  Vector3 nearestNormal;
[170]261  int nearestFace = -1;
[1199]262 
[170]263  if (ray.GetType() == Ray::LOCAL_RAY && ray.intersections.size())
264    nearestT = ray.intersections[0].mT;
265
266  for ( fi = faces.begin();
[878]267                fi != faces.end();
268                fi++) {
[1199]269    hits += CastRayToFace(*fi, ray, nearestT, nearestNormal, nearestFace, instance);
[170]270    if (mIsConvex && nearestFace != -1)
271      break;
272  }
273 
274  if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
275    if (ray.intersections.size())
[1199]276      ray.intersections[0] = Ray::Intersection(nearestT, nearestNormal,instance, nearestFace);
[170]277    else
[1199]278      ray.intersections.push_back(Ray::Intersection(nearestT, nearestNormal,instance, nearestFace));
[170]279  }
280 
281  return hits;
282}
283
284
[162]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,
[492]290                        float py,
291                        float u1,
292                        float v1,
293                        float u2,
294                        float v2)
[162]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) ||
[492]312                 (u1 > 0) || (u2 > 0)))
[162]313      return 0;
314    return 1;
315  }
[492]316 
317  double t = -v1 / ydiff;                 // Compute parameter
[162]318
[492]319  double thresh;
[878]320
[492]321  if (ydiff < 0.0f)
[878]322        thresh = -1e-20;
[492]323  else
[878]324        thresh = 1e-20;
[162]325
[492]326 
327  return (u1 + t * (u2 - u1)) > thresh; //-Limits::Small;
[162]328}
329
330
331
332// intersection with the polygonal face of the mesh
333int
334Mesh::RayFaceIntersection(const int faceIndex,
[492]335                                                  const Ray &ray,
336                                                  float &t,
[1199]337                                                  Vector3 &normal,
[492]338                                                  const float nearestT
339                                                  )
[162]340{
341  Face *face  = mFaces[faceIndex];
342
343  Plane3 plane = GetFacePlane(faceIndex);
344  float dot = DotProd(plane.mNormal, ray.GetDir());
[878]345
346  if (MeshDebug) {
347        cout<<endl<<endl;
348        cout<<"normal="<<plane.mNormal<<endl;
349        cout<<"dot="<<dot<<endl;
350  }
[162]351 
[878]352       
[162]353  // Watch for near-zero denominator
354  // ONLY single sided polygons!!!!!
[534]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  }
[162]363 
[1199]364  normal = plane.mNormal;
365
[162]366  t = (-plane.mD - DotProd(plane.mNormal, ray.GetLoc())) / dot;
[878]367
368  if (MeshDebug)
369        cout<<"t="<<t<<endl;
370
[162]371  if (t <= Limits::Small)
372    return Ray::INTERSECTION_OUT_OF_LIMITS;
373 
[1867]374  if ((ray.GetType() == Ray::LOCAL_RAY) && (t >= nearestT)) {
[162]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
[878]384 
[162]385  // Project the intersection point onto the coordinate plane
386  // specified by which.
387  ray.Extrap(t).ExtractVerts(&u, &v, paxis);
388
389
[469]390  int size = (int)face->mVertexIndices.size();
[170]391
[878]392  if (MeshDebug)
393        cout<<"size="<<size<<endl;
394 
[170]395  mVertices[face->mVertexIndices[size - 1]].
[162]396    ExtractVerts(&u1, &v1, paxis );
[170]397 
[752]398  //$$JB changed 12.4.2006 from 0 ^^
[170]399  if (0 && size <= 4) {
[162]400    // assume a convex face
[170]401    for (i = 0; i < size; i++) {
[162]402      mVertices[face->mVertexIndices[i]].ExtractVerts(&u2, &v2, paxis);
403      // line u1, v1, u2, v2
[878]404      if ((v1 - v2)*(u - u1) + (u2 - u1)*(v - v1) > 0) {
405                if (MeshDebug)
406                  cout<<"exit on "<<i<<endl;
[492]407                return Ray::NO_INTERSECTION;
[878]408          }
[162]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.
[170]420  for (i = 0; i < size; i++) {
[162]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
[878]427  if (MeshDebug)
428        cout<<"count="<<count<<endl;
429
[162]430  // We hit polygon if number of intersections is odd.
431  return (count & 1) ? Ray::INTERSECTION : Ray::NO_INTERSECTION;
432}
433
[349]434int
[176]435Mesh::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal)
436{
[1772]437        //const int faceIndex = (int)RandomValue(0, (Real)((int)mFaces.size()-1));
[1586]438        const int faceIndex = (int)RandomValue(0, (Real)mFaces.size() - 0.5f);
439
[1772]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
[340]453        normal = GetFacePlane(faceIndex).mNormal;
[349]454
455        return faceIndex;
[176]456}
457
[162]458int
[354]459Mesh::GetRandomVisibleSurfacePoint(Vector3 &point,
[1001]460                                                                   Vector3 &normal,
461                                                                   const Vector3 &viewpoint,
462                                                                   const int maxTries)
[354]463{
[359]464  Plane3 plane;
[1586]465  const int faceIndex = (int)RandomValue(0, (Real)mFaces.size() - 0.5f);
[359]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++) {
[354]476                                float r = RandomValue(0,1);
477                                sum += r;
478                                point += mVertices[face->mVertexIndices[i]]*r;
[359]479      }
480      point *= 1.0f/sum;
481      break;
482    }
483  }
484 
485  normal = plane.mNormal;
486  return (tries < maxTries) ? faceIndex + 1 : 0;
[354]487}
488
489
[162]490Plane3
[1418]491Mesh::GetFacePlane(const int faceIndex) const
[162]492{
493  Face *face = mFaces[faceIndex];
[340]494        return Plane3(mVertices[face->mVertexIndices[0]],
[333]495                                                                mVertices[face->mVertexIndices[1]],
496                                                                mVertices[face->mVertexIndices[2]]);
[162]497}
498
[340]499bool
500Mesh::ValidateFace(const int i)
501{
502        Face *face = mFaces[i];
503
504        Plane3 plane = Plane3(mVertices[face->mVertexIndices[0]],
[1076]505                                                  mVertices[face->mVertexIndices[1]],
506                                                  mVertices[face->mVertexIndices[2]]);
[340]507       
508        if (!eq(Magnitude(plane.mNormal), 1.0f))
509                return false;
[350]510
511        return true;
[340]512}
513
[1419]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
[1420]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
[1419]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
[1420]561        for (int i = 0; i < (int)mFaces.size(); ++ i)
[1419]562        {
[1420]563                PrintFace(this, i, app);
[1419]564        }
565}
566
567
[340]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
[170]589
[1418]590Vector3 Mesh::GetNormal(const int idx) const
591{
592        return GetFacePlane(idx).mNormal;
593}
594
595
[191]596void
597Mesh::AddTriangle(const Triangle3 &triangle)
598{
[469]599  int index = (int)mVertices.size();
[191]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}
[209]607
608void
609Mesh::AddRectangle(const Rectangle3 &rect)
610{
[469]611  int index = (int)mVertices.size();
[209]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}
[750]619
[752]620void
621Mesh::AssignRandomMaterial()
[1001]622
623        mMaterial = MaterialManager::GetSingleton()->CreateResource();
624 
625        Material randMat = RandomMaterial();
[750]626
[1001]627        mMaterial->mDiffuseColor = randMat.mDiffuseColor;
628        mMaterial->mSpecularColor = randMat.mSpecularColor;
629        mMaterial->mAmbientColor = randMat.mAmbientColor;
[752]630}
[750]631
[752]632
[991]633Mesh *CreateMeshFromBox(const AxisAlignedBox3 &box)
[750]634{
[1001]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) );
[750]650 
[1001]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) );
[750]654 
[1001]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
[1020]690Mesh::Mesh(const Mesh &rhs):
691mKdTree(NULL)
[1001]692{
693        mVertices = rhs.mVertices;
694        mFaces.reserve(rhs.mFaces.size());
695        mId = rhs.mId;
[1002]696        mMaterial = rhs.mMaterial;
[1020]697       
[1001]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());
[1002]717        mMaterial = m.mMaterial;
718        // note: we don't copy id on purpose
[1001]719        //mId = m.mId;
[1002]720       
[1001]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
[1005]733Mesh::~Mesh()
734{
735        for (int i=0; i < mFaces.size(); ++ i)
736                delete mFaces[i];
[1001]737
[1005]738        DEL_PTR(mKdTree);
739}
740 
741
742void Mesh::Clear()
743{
744        mVertices.clear();
745        mFaces.clear();
746
747        DEL_PTR(mKdTree);
748}
749
[1449]750
751
[1001]752/********************************************************/
753/*                      MeshInstance implementation             */
754/********************************************************/
755
756int
757MeshInstance::CastRay(
758                                          Ray &ray
759                                          )
760{
761  int res = mMesh->CastRay(ray, this);
[1990]762
[1001]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
[1344]804Vector3 MeshInstance::GetNormal(const int idx) const
805{
[1418]806        return mMesh->GetNormal(idx);
[1344]807}
808
809
[1763]810int MeshInstance::GetRandomEdgePoint(Vector3 &point, Vector3 &normal)
811{
[1768]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!
[1769]817        const int edgeIdx = (int)RandomValue(0.0f, (float)face->mVertexIndices.size() - 0.5f);
[1768]818
[1769]819        //cout << "idx = " << edgeIdx << " s: " << face->mVertexIndices.size() << endl;
[1768]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
[1769]831        //cout << "va " << a << " vb " << b << "p " << point << endl;
[1768]832        // hack: set normal of face as normal
833        normal = mMesh->GetFacePlane(faceIdx).mNormal;
834
835    return 1;
[1763]836}
[1344]837
[1763]838
[1001]839/*************************************************************/
[1002]840/*           TransformedMeshInstance implementation          */
[1001]841/*************************************************************/
842
[1344]843
[1001]844TransformedMeshInstance::TransformedMeshInstance(Mesh *mesh):
845MeshInstance(mesh)
846{
847    mWorldTransform = IdentityMatrix();
848}
849
850
851int TransformedMeshInstance::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal)
852{
[1587]853  const int index = mMesh->GetRandomSurfacePoint(point, normal);
854  point = mWorldTransform * point;
[1001]855  normal = TransformNormal(mWorldTransform, normal);
856  return index;
857}
858
859
860int TransformedMeshInstance::CastRay(Ray &ray)
861{
[1004]862        ray.ApplyTransform(Invert(mWorldTransform));
863       
864        const int res = mMesh->CastRay(ray, this);
865        ray.ApplyTransform(mWorldTransform);
866
867    return res;
[863]868}
869
[1344]870
[1004]871int TransformedMeshInstance::CastRay(Ray &ray, const vector<int> &faces)
872{
873        ray.ApplyTransform(Invert(mWorldTransform));
[1001]874
[1004]875        const int res = mMesh->CastRayToSelectedFaces(ray, faces, this);
876        ray.ApplyTransform(mWorldTransform);
877
878         return res;
879}
880
881
[1001]882void TransformedMeshInstance::ApplyWorldTransform(const Matrix4x4 &m)
883{
884        mWorldTransform = m * mWorldTransform;
[878]885}
[1001]886
887
888void TransformedMeshInstance::LoadWorldTransform(const Matrix4x4 &m)
889{
890        mWorldTransform = m;
891}
892
893
[1020]894void TransformedMeshInstance::GetWorldTransform(Matrix4x4 &m) const
[1001]895{
896        m = mWorldTransform;
897}
898
899
[1020]900AxisAlignedBox3 TransformedMeshInstance::GetBox() const
[1001]901{
902    return Transform(mMesh->mBox, mWorldTransform);
903}
904
[1020]905
906void TransformedMeshInstance::GetTransformedMesh(Mesh &transformedMesh) const
907{
908        // copy mesh
[1002]909        transformedMesh = *mMesh;
910        transformedMesh.ApplyTransformation(mWorldTransform);
[1020]911}
[1001]912
[1328]913
[1344]914Vector3 TransformedMeshInstance::GetNormal(const int idx) const
915{
916        Mesh mesh;
917        GetTransformedMesh(mesh);
918        return mesh.GetFacePlane(idx).mNormal;
[1001]919}
[1344]920
921}
Note: See TracBrowser for help on using the repository browser.