MCPcopy Create free account
hub / github.com/cinder/Cinder / performPicking

Method performPicking

samples/Picking3D/src/Picking3DApp.cpp:130–200  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

128}
129
130bool Picking3DApp::performPicking( vec3 *pickedPoint, vec3 *pickedNormal )
131{
132 // Generate a ray from the camera into our world. Note that we have to
133 // flip the vertical coordinate.
134 float u = mMousePos.x / (float) getWindowWidth();
135 float v = mMousePos.y / (float) getWindowHeight();
136 Ray ray = mCamera.generateRay( u, 1.0f - v, mCamera.getAspectRatio() );
137
138 // The coordinates of the bounding box are in object space, not world space,
139 // so if the model was translated, rotated or scaled, the bounding box would not
140 // reflect that. One solution would be to pass the transformation to the calcBoundingBox() function:
141 AxisAlignedBox worldBoundsExact = mTriMesh->calcBoundingBox( mTransform ); // slow
142
143 // But if you already have an object space bounding box, it's much faster to
144 // approximate the world space bounding box like this:
145 AxisAlignedBox worldBoundsApprox = mObjectBounds.transformed( mTransform ); // fast
146
147 // Draw the object space bounding box in yellow. It will not animate,
148 // because animation is done in world space.
149 drawCube( mObjectBounds, Color( 1, 1, 0 ) );
150
151 // Draw the exact bounding box in orange.
152 drawCube( worldBoundsExact, Color( 1, 0.5f, 0 ) );
153
154 // Draw the approximated bounding box in cyan.
155 drawCube( worldBoundsApprox, Color( 0, 1, 1 ) );
156
157 // Perform fast detection first - test against the bounding box itself.
158 if( ! worldBoundsExact.intersects( ray ) )
159 return false;
160
161 // Set initial distance to something far, far away.
162 float result = FLT_MAX;
163
164 // Traverse triangle list and find the closest intersecting triangle.
165 const size_t polycount = mTriMesh->getNumTriangles();
166
167 float distance = 0.0f;
168 for( size_t i = 0; i < polycount; ++i ) {
169 // Get a single triangle from the mesh.
170 vec3 v0, v1, v2;
171 mTriMesh->getTriangleVertices( i, &v0, &v1, &v2 );
172
173 // Transform triangle to world space.
174 v0 = vec3( mTransform * vec4( v0, 1.0 ) );
175 v1 = vec3( mTransform * vec4( v1, 1.0 ) );
176 v2 = vec3( mTransform * vec4( v2, 1.0 ) );
177
178 // Test to see if the ray intersects this triangle.
179 if( ray.calcTriangleIntersection( v0, v1, v2, &distance ) ) {
180 // Keep the result if it's closer than any intersection we've had so far.
181 if( distance < result ) {
182 result = distance;
183
184 // Assuming this is the closest triangle, we'll calculate our normal
185 // while we've got all the points handy.
186 *pickedNormal = normalize( cross( v1 - v0, v2 - v0 ) );
187 }

Callers

nothing calls this directly

Calls 11

getWindowWidthFunction · 0.85
getWindowHeightFunction · 0.85
drawCubeFunction · 0.85
getTriangleVerticesMethod · 0.80
ColorFunction · 0.50
normalizeFunction · 0.50
getAspectRatioMethod · 0.45
calcBoundingBoxMethod · 0.45
transformedMethod · 0.45
intersectsMethod · 0.45

Tested by

no test coverage detected