Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/ode/src/collision_trimesh_ray.cpp @ 216

Last change on this file since 216 was 216, checked in by mathiask, 16 years ago

[Physik] add ode-0.9

File size: 6.5 KB
Line 
1/*************************************************************************
2 *                                                                       *
3 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
4 * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
5 *                                                                       *
6 * This library is free software; you can redistribute it and/or         *
7 * modify it under the terms of EITHER:                                  *
8 *   (1) The GNU Lesser General Public License as published by the Free  *
9 *       Software Foundation; either version 2.1 of the License, or (at  *
10 *       your option) any later version. The text of the GNU Lesser      *
11 *       General Public License is included with this library in the     *
12 *       file LICENSE.TXT.                                               *
13 *   (2) The BSD-style license that is included with this library in     *
14 *       the file LICENSE-BSD.TXT.                                       *
15 *                                                                       *
16 * This library is distributed in the hope that it will be useful,       *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
19 * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
20 *                                                                       *
21 *************************************************************************/
22
23// TriMesh code by Erwin de Vries.
24
25#include <ode/collision.h>
26#include <ode/matrix.h>
27#include <ode/rotation.h>
28#include <ode/odemath.h>
29
30#if dTRIMESH_ENABLED
31
32#include "collision_util.h"
33
34#define TRIMESH_INTERNAL
35#include "collision_trimesh_internal.h"
36
37#if dTRIMESH_OPCODE
38int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride){
39        dIASSERT (Stride >= (int)sizeof(dContactGeom));
40        dIASSERT (g1->type == dTriMeshClass);
41        dIASSERT (RayGeom->type == dRayClass);
42        dIASSERT ((Flags & NUMC_MASK) >= 1);
43
44        dxTriMesh* TriMesh = (dxTriMesh*)g1;
45
46        const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh);
47        const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh);
48
49        RayCollider& Collider = TriMesh->_RayCollider;
50
51        dReal Length = dGeomRayGetLength(RayGeom);
52
53        int FirstContact, BackfaceCull;
54        dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull);
55        int ClosestHit = dGeomRayGetClosestHit(RayGeom);
56
57        Collider.SetFirstContact(FirstContact != 0);
58        Collider.SetClosestHit(ClosestHit != 0);
59        Collider.SetCulling(BackfaceCull != 0);
60        Collider.SetMaxDist(Length);
61
62        dVector3 Origin, Direction;
63        dGeomRayGet(RayGeom, Origin, Direction);
64
65        /* Make Ray */
66        Ray WorldRay;
67        WorldRay.mOrig.x = Origin[0];
68        WorldRay.mOrig.y = Origin[1];
69        WorldRay.mOrig.z = Origin[2];
70        WorldRay.mDir.x = Direction[0];
71        WorldRay.mDir.y = Direction[1];
72        WorldRay.mDir.z = Direction[2];
73
74        /* Intersect */
75        Matrix4x4 amatrix;
76        int TriCount = 0;
77        if (Collider.Collide(WorldRay, TriMesh->Data->BVTree, &MakeMatrix(TLPosition, TLRotation, amatrix))) {
78                TriCount = TriMesh->Faces.GetNbFaces();
79        }
80
81        if (TriCount == 0) {
82                return 0;
83        }
84       
85        const CollisionFace* Faces = TriMesh->Faces.GetFaces();
86
87        int OutTriCount = 0;
88        for (int i = 0; i < TriCount; i++) {
89                if (TriMesh->RayCallback == null ||
90                    TriMesh->RayCallback(TriMesh, RayGeom, Faces[i].mFaceID,
91                                         Faces[i].mU, Faces[i].mV)) {
92                        const int& TriIndex = Faces[i].mFaceID;
93                        if (!Callback(TriMesh, RayGeom, TriIndex)) {
94                                continue;
95                        }
96
97                        dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride);
98
99                        dVector3 dv[3];
100                        FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv);
101
102                        // No sense to save on single type conversion in algorithm of this size.
103                        // If there would be a custom typedef for distance type it could be used
104                        // instead of dReal. However using float directly is the loss of abstraction
105                        // and possible loss of precision in future.
106                        /*float*/ dReal T = Faces[i].mDistance;
107                        Contact->pos[0] = Origin[0] + (Direction[0] * T);
108                        Contact->pos[1] = Origin[1] + (Direction[1] * T);
109                        Contact->pos[2] = Origin[2] + (Direction[2] * T);
110                        Contact->pos[3] = REAL(0.0);
111                               
112                        dVector3 vu;
113                        vu[0] = dv[1][0] - dv[0][0];
114                        vu[1] = dv[1][1] - dv[0][1];
115                        vu[2] = dv[1][2] - dv[0][2];
116                        vu[3] = REAL(0.0);
117                               
118                        dVector3 vv;
119                        vv[0] = dv[2][0] - dv[0][0];
120                        vv[1] = dv[2][1] - dv[0][1];
121                        vv[2] = dv[2][2] - dv[0][2];
122                        vv[3] = REAL(0.0);
123
124                        dCROSS(Contact->normal, =, vv, vu);     // Reversed
125
126                        dNormalize3(Contact->normal);
127
128                        Contact->depth = T;
129                        Contact->g1 = TriMesh;
130                        Contact->g2 = RayGeom;
131                               
132                        OutTriCount++;
133
134                        // Putting "break" at the end of loop prevents unnecessary checks on first pass and "continue"
135                        if (OutTriCount >= (Flags & NUMC_MASK)) {
136                                break;
137                        }
138                }
139        }
140        return OutTriCount;
141}
142#endif // dTRIMESH_OPCODE
143
144#if dTRIMESH_GIMPACT
145int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride)
146{
147        dIASSERT (Stride >= (int)sizeof(dContactGeom));
148        dIASSERT (g1->type == dTriMeshClass);
149        dIASSERT (RayGeom->type == dRayClass);
150        dIASSERT ((Flags & NUMC_MASK) >= 1);
151       
152        dxTriMesh* TriMesh = (dxTriMesh*)g1;
153
154    dReal Length = dGeomRayGetLength(RayGeom);
155        int FirstContact, BackfaceCull;
156        dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull);
157        int ClosestHit = dGeomRayGetClosestHit(RayGeom);
158        dVector3 Origin, Direction;
159        dGeomRayGet(RayGeom, Origin, Direction);
160
161    char intersect=0;
162    GIM_TRIANGLE_RAY_CONTACT_DATA contact_data;
163
164        if(ClosestHit)
165        {
166                intersect = gim_trimesh_ray_closest_collision(&TriMesh->m_collision_trimesh,Origin,Direction,Length,&contact_data);
167        }
168        else
169        {
170            intersect = gim_trimesh_ray_collision(&TriMesh->m_collision_trimesh,Origin,Direction,Length,&contact_data);
171        }
172
173    if(intersect == 0)
174        {
175        return 0;
176    }
177
178        int OutTriCount = 0;
179
180        if(!TriMesh->RayCallback || 
181                TriMesh->RayCallback(TriMesh, RayGeom, contact_data.m_face_id, contact_data.u , contact_data.v))
182        {
183                dContactGeom* Contact = SAFECONTACT(Flags, Contacts, (OutTriCount-1), Stride);
184        VEC_COPY(Contact->pos,contact_data.m_point);
185        VEC_COPY(Contact->normal,contact_data.m_normal);
186        Contact->depth = contact_data.tparam;
187        Contact->g1 = TriMesh;
188        Contact->g2 = RayGeom;
189               
190                OutTriCount = 1;
191        }
192
193        return OutTriCount;
194}
195#endif  // dTRIMESH_GIMPACT
196
197#endif // dTRIMESH_ENABLED
198
Note: See TracBrowser for help on using the repository browser.