aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/OPCODE/OPC_Picking.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/ode-0.9/OPCODE/OPC_Picking.cpp182
1 files changed, 0 insertions, 182 deletions
diff --git a/libraries/ode-0.9/OPCODE/OPC_Picking.cpp b/libraries/ode-0.9/OPCODE/OPC_Picking.cpp
deleted file mode 100644
index 3b53774..0000000
--- a/libraries/ode-0.9/OPCODE/OPC_Picking.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/*
3 * OPCODE - Optimized Collision Detection
4 * Copyright (C) 2001 Pierre Terdiman
5 * Homepage: http://www.codercorner.com/Opcode.htm
6 */
7///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8
9///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10/**
11 * Contains code to perform "picking".
12 * \file OPC_Picking.cpp
13 * \author Pierre Terdiman
14 * \date March, 20, 2001
15 */
16///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17
18///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19// Precompiled Header
20#include "Stdafx.h"
21
22using namespace Opcode;
23
24#ifdef OPC_RAYHIT_CALLBACK
25
26/*
27 Possible RayCollider usages:
28 - boolean query (shadow feeler)
29 - closest hit
30 - all hits
31 - number of intersection (boolean)
32
33*/
34
35bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts)
36{
37 struct Local
38 {
39 static void AllContacts(const CollisionFace& hit, void* user_data)
40 {
41 CollisionFaces* CF = (CollisionFaces*)user_data;
42 CF->AddFace(hit);
43 }
44 };
45
46 collider.SetFirstContact(false);
47 collider.SetHitCallback(Local::AllContacts);
48 collider.SetUserData(&contacts);
49 return true;
50}
51
52bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact)
53{
54 struct Local
55 {
56 static void ClosestContact(const CollisionFace& hit, void* user_data)
57 {
58 CollisionFace* CF = (CollisionFace*)user_data;
59 if(hit.mDistance<CF->mDistance) *CF = hit;
60 }
61 };
62
63 collider.SetFirstContact(false);
64 collider.SetHitCallback(Local::ClosestContact);
65 collider.SetUserData(&closest_contact);
66 closest_contact.mDistance = MAX_FLOAT;
67 return true;
68}
69
70bool Opcode::SetupShadowFeeler(RayCollider& collider)
71{
72 collider.SetFirstContact(true);
73 collider.SetHitCallback(null);
74 return true;
75}
76
77bool Opcode::SetupInOutTest(RayCollider& collider)
78{
79 collider.SetFirstContact(false);
80 collider.SetHitCallback(null);
81 // Results with collider.GetNbIntersections()
82 return true;
83}
84
85bool Opcode::Picking(
86CollisionFace& picked_face,
87const Ray& world_ray, const Model& model, const Matrix4x4* world,
88float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data)
89{
90 struct Local
91 {
92 struct CullData
93 {
94 CollisionFace* Closest;
95 float MinLimit;
96 CullModeCallback Callback;
97 void* UserData;
98 Point ViewPoint;
99 const MeshInterface* IMesh;
100 };
101
102 // Called for each stabbed face
103 static void RenderCullingCallback(const CollisionFace& hit, void* user_data)
104 {
105 CullData* Data = (CullData*)user_data;
106
107 // Discard face if we already have a closer hit
108 if(hit.mDistance>=Data->Closest->mDistance) return;
109
110 // Discard face if hit point is smaller than min limit. This mainly happens when the face is in front
111 // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an
112 // object that he may not even be able to see, which is very annoying.
113 if(hit.mDistance<=Data->MinLimit) return;
114
115 // This is the index of currently stabbed triangle.
116 udword StabbedFaceIndex = hit.mFaceID;
117
118 // We may keep it or not, depending on backface culling
119 bool KeepIt = true;
120
121 // Catch *render* cull mode for this face
122 CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData);
123
124 if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles
125 {
126 // Compute backface culling for current face
127
128 VertexPointers VP;
129 Data->IMesh->GetTriangle(VP, StabbedFaceIndex);
130 if(VP.BackfaceCulling(Data->ViewPoint))
131 {
132 if(CM==CULLMODE_CW) KeepIt = false;
133 }
134 else
135 {
136 if(CM==CULLMODE_CCW) KeepIt = false;
137 }
138 }
139
140 if(KeepIt) *Data->Closest = hit;
141 }
142 };
143
144 RayCollider RC;
145 RC.SetMaxDist(max_dist);
146 RC.SetTemporalCoherence(false);
147 RC.SetCulling(false); // We need all faces since some of them can be double-sided
148 RC.SetFirstContact(false);
149 RC.SetHitCallback(Local::RenderCullingCallback);
150
151 picked_face.mFaceID = INVALID_ID;
152 picked_face.mDistance = MAX_FLOAT;
153 picked_face.mU = 0.0f;
154 picked_face.mV = 0.0f;
155
156 Local::CullData Data;
157 Data.Closest = &picked_face;
158 Data.MinLimit = min_dist;
159 Data.Callback = callback;
160 Data.UserData = user_data;
161 Data.ViewPoint = view_point;
162 Data.IMesh = model.GetMeshInterface();
163
164 if(world)
165 {
166 // Get matrices
167 Matrix4x4 InvWorld;
168 InvertPRMatrix(InvWorld, *world);
169
170 // Compute camera position in mesh space
171 Data.ViewPoint *= InvWorld;
172 }
173
174 RC.SetUserData(&Data);
175 if(RC.Collide(world_ray, model, world))
176 {
177 return picked_face.mFaceID!=INVALID_ID;
178 }
179 return false;
180}
181
182#endif