bool QuadTree::Pick(D3DXVECTOR3 vPickRayDir, D3DXVECTOR3 vPickRayOrig, BoxNode box) { /* |\ | \ |__\ */ D3DXVECTOR3 v0 = box.minB; D3DXVECTOR3 v1 = D3DXVECTOR3(box.minB.x, pLand->getHeight(box.minB.x, box.maxB.z)+1, box.maxB.z); D3DXVECTOR3 v2 = D3DXVECTOR3(box.maxB.x, pLand->getHeight(box.maxB.x, box.minB.z)+1, box.minB.z); /* ___ \ | \ | \| */ D3DXVECTOR3 v3 = v1; D3DXVECTOR3 v4 = v2; D3DXVECTOR3 v5 = box.maxB; //Check if the pick ray passes through triangles if( IntersectTriangle( vPickRayOrig, vPickRayDir, v0, v1, v2) ) return true; else if( IntersectTriangle( vPickRayOrig, vPickRayDir, v3, v4, v5) ) return true; return false; }
bool RayTesselatedTrianglePrimitive::Intersect(const Ray& ray, Intersection* intersection) { Vec3f v0, v1, v2; _ResolveVertexAttrib(v0,v1,v2,triangles->pos); float t, b1, b2, rayEpsilon; bool hit = IntersectTriangle(v0,v1,v2,ray, &t, &b1, &b2, &rayEpsilon); if(hit) { // geometry intersection->t = t; intersection->rayEpsilon = rayEpsilon; intersection->dp.P = ray.Eval(t); intersection->dp.uv = Vec2f(b1,b2); if(triangles->normal.empty()) { intersection->dp.Ng = triangles->faceNormal[idx]; intersection->dp.N = triangles->faceNormal[idx]; } else { intersection->dp.Ng = ElementOperations::TriangleNormal(v0,v1,v2); intersection->dp.N = _InterpolateVertexAttrib(b1,b2,triangles->normal).GetNormalized(); } intersection->dp.GenerateTuTv(); // shading if(triangles->uv.empty()) { intersection->dp.st = intersection->dp.uv; } else { intersection->dp.st = _InterpolateVertexAttrib(b1,b2,triangles->uv); } // material intersection->m = material; } return hit; }
bool IsShadowed(int currPrimitiveNum, Ray &rayToLight, float distanceToLight, Primitive *primitives, int numPrimitives) { TraceResult traceResult; traceResult.hit=false; // check all spheres for(int i=0; i<numPrimitives; i++) { if( i == currPrimitiveNum ) continue;//no auto switch(primitives[i].type) { case SPHERE_TYPE: traceResult = IntersectSphere(*primitives[i].sphereProperties, rayToLight); break; case PLANE_TYPE: traceResult = IntersectPlane(*primitives[i].planeProperties, rayToLight); break; case CYLINDER_TYPE: traceResult = IntersectCylinder(*primitives[i].cylinderProperties, rayToLight); break; case TRIANGLE_TYPE: traceResult = IntersectTriangle(*primitives[i].triangleProperties, rayToLight); break; default: continue; break; } if( traceResult.hit && (traceResult.distance < distanceToLight) ) return true; } return false; }
Bool kDOPTree::LineCheck( kDOPNode* pNode, const Ray3f& pRay ) const { if( Intersect( pRay, pNode->mBoundingBox ) ) { // At the root. if( pNode->mTriangleIndices.size() != 0 ) { // Check each triangles. const Trianglef* tri; for( UInt32 i = 0; i < pNode->mTriangleIndices.size(); i++ ) { tri = &mTriangles[pNode->mTriangleIndices[i]]; if( IntersectTriangle( mVertices[tri->mIndices[0]], mVertices[tri->mIndices[1]], mVertices[tri->mIndices[2]], pRay ) ) return true; } return false; } else { // Check childs. return LineCheck( mNodes[pNode->mChildsIndex + 0], pRay ) || LineCheck( mNodes[pNode->mChildsIndex + 1], pRay ); } } return false; }
bool TriObj::TraceBVHNode(const Ray& ray, HitInfo& hInfo, int hitSide, unsigned nodeID) const { bool isHit = false; if(bvh.IsLeafNode(nodeID)) { if(Box(bvh.GetNodeBounds(nodeID)).IntersectRay(ray,hInfo.z)) { unsigned int noOfFacesInLeafNode = bvh.GetNodeElementCount(nodeID); for (int i = 0; i < noOfFacesInLeafNode; i++) { isHit |= IntersectTriangle(ray, hInfo, hitSide, bvh.GetNodeElements(nodeID)[i]); } } else { isHit = false; } } else { isHit |= TraceBVHNode(ray, hInfo, hitSide, bvh.GetFirstChildNode(nodeID)); isHit |= TraceBVHNode(ray, hInfo, hitSide, bvh.GetSecondChildNode(nodeID)); } return isHit; }
/** Intersects the whole primitive. If hit, it returns a distance other than -1 */ float EditorLinePrimitive::IntersectPrimitive(D3DXVECTOR3* RayOrigin, D3DXVECTOR3* RayDirection, float Epsilon) { UINT i; float Shortest = -1; // Bring the ray into object space D3DXMATRIX invWorld; D3DXMatrixInverse(&invWorld, NULL, &WorldMatrix); D3DXVECTOR3 Origin; D3DXVECTOR3 Dir; D3DXVec3TransformCoord(&Origin, RayOrigin, &invWorld); D3DXVec3TransformNormal(&Dir, RayDirection, &invWorld); // Go through all line segments and intersect them for(i = 0; i < NumVertices; i+=2) { D3DXVECTOR3 vx[2]; D3DXVec3TransformCoord(&vx[0], Vertices[i].Position.toD3DXVECTOR3(), &WorldMatrix); D3DXVec3TransformCoord(&vx[1], Vertices[i+1].Position.toD3DXVECTOR3(), &WorldMatrix); //float Dist = IntersectLineSegment(&Origin, &Dir, Vertices[i].Position.toD3DXVECTOR3(), Vertices[i+1].Position.toD3DXVECTOR3(), Epsilon); float Dist = IntersectLineSegment(RayOrigin, RayDirection, &vx[0], &vx[1], Epsilon); if(Dist < Shortest || Shortest == -1) { Shortest = Dist / Scale.x; } } if(NumSolidVertices>0) { FLOAT fBary1, fBary2; FLOAT fDist; int NumIntersections=0; Shortest = FLT_MAX; for( DWORD i = 0; i < NumSolidVertices; i+=3 ) { D3DXVECTOR3 v0 = *SolidVertices[i + 0].Position.toD3DXVECTOR3(); D3DXVECTOR3 v1 = *SolidVertices[i + 1].Position.toD3DXVECTOR3(); D3DXVECTOR3 v2 = *SolidVertices[i + 2].Position.toD3DXVECTOR3(); // Check if the pick ray passes through this point if( IntersectTriangle( &Origin, &Dir, v0, v1, v2, &fDist, &fBary1, &fBary2 ) ) { if( fDist < Shortest || Shortest == -1) { NumIntersections++; Shortest=0; //if( NumIntersections == MAX_INTERSECTIONS ) // break; } } } } return Shortest; }
bool CObject::Pick(const D3DXVECTOR3& origin, const D3DXVECTOR3& dir, float& dist) { static int indexTable[12 * 3] = { 3, 2, 6, 3, 6, 7, 0, 3, 7, 0, 7, 4, 1, 2, 6, 1, 6, 5, 0, 1, 2, 0, 2, 3, 0, 4, 5, 0, 5, 1, 4, 5, 6, 4, 6, 7 }; bool pick = false; float tempDist; dist = 65535.0f; for (int i = 0; i < 12 * 3; i += 3) { if (IntersectTriangle(m_bounds[indexTable[i]], m_bounds[indexTable[i + 1]], m_bounds[indexTable[i + 2]], origin, dir, tempDist) && tempDist < dist) { dist = tempDist; pick = true; } } if (pick) { if (m_modelProp->modelType == MODELTYPE_SFX) return true; else return m_model->Pick(m_TM, origin, dir, dist); } return false; }
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool /*pStopAtFirstHit*/) { bool result = IntersectTriangle(triangles[entry], vertices, ray, distance); if (result) hit = true; return hit; }
float IntersectTriangle_KDtree(float *Di,int *Uaxis,int *Vaxis,int *Waxis,float *lambda_num,float *bnu,float *bnv,float *cnu,float *cnv,float *Cu,float *Cv,float *nu,float *nv,float *vu,float *vv,KDtree *kd,float min_lambda,float max_lambda,float *C,int *jmax) { // Base case: if((kd->left==NULL) && (kd->right==NULL)) { // Intersect with leaf node's triangles: return IntersectTriangle(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->leaves,kd->dim,jmax); } float val_min = Di[kd->dim]*min_lambda+C[kd->dim]; float val_max = Di[kd->dim]*max_lambda+C[kd->dim]; // Check to see which side of plane (or both) ray lies on: if((val_min<=kd->split_direction) && (val_max<=kd->split_direction)) { // Go left: if(kd->left) { return IntersectTriangle_KDtree(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->left,min_lambda,max_lambda,C,jmax); } else return -INF; } else if((val_min>kd->split_direction) && (val_max>kd->split_direction)) { // Go right: if(kd->right) { return IntersectTriangle_KDtree(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->right,min_lambda,max_lambda,C,jmax); } else return -INF; } else { // Intersect ray with splitting direction plane: float lambda = (kd->split_direction-C[kd->dim])/Di[kd->dim]; // Try partition that is closest to camera center: float maxLambda = -INF; if(C[kd->dim]<=kd->split_direction) { if(kd->left) { maxLambda = IntersectTriangle_KDtree(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->left,min_lambda,lambda,C,jmax); } } else if(kd->right) { maxLambda = IntersectTriangle_KDtree(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->right,min_lambda,lambda,C,jmax); } if((min_lambda>=maxLambda)&&(maxLambda>=lambda)) return maxLambda; // Otherwise, try other partition: if(C[kd->dim]<=kd->split_direction) { if(kd->right) { maxLambda = IntersectTriangle_KDtree(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->right,lambda,max_lambda,C,jmax); } } else if(kd->left) { maxLambda = IntersectTriangle_KDtree(Di,Uaxis,Vaxis,Waxis,lambda_num,bnu,bnv,cnu,cnv,Cu,Cv,nu,nv,vu,vv,kd->left,lambda,max_lambda,C,jmax); } return maxLambda; } }
bool CUtils::IntersectTriangle(const CRay &i_Ray, CIntersactionInfo &io_IntersectionInfo, const CVector3DF& i_vA, const CVector3DF& i_vB, const CVector3DF& i_vC, const CVector3DF& i_vABar, const CVector3DF& i_vBBar, const CVector3DF& i_vCBar) { if (!IntersectTriangle(i_Ray, io_IntersectionInfo, i_vA, i_vB, i_vC)) { return false; } const CVector3DF vPA = i_vABar * io_IntersectionInfo.m_vBarCoordsLocal.X(); const CVector3DF vPB = i_vBBar * io_IntersectionInfo.m_vBarCoordsLocal.Y(); const CVector3DF vPC = i_vCBar * io_IntersectionInfo.m_vBarCoordsLocal.Z(); io_IntersectionInfo.m_vBarCoordsGlobal = vPA + vPB + vPC; return true; }
BOOL CBuildingCollisionMng::SelBuilding( FLOAT fOrigx, FLOAT fOrigy, FLOAT fOrigz, // 射线的原点。 FLOAT fDirx, FLOAT fDiry, FLOAT fDirz, // 射线的方向。 INT ix, INT iz, // 选中地图的位置 FLOAT& fPosx, FLOAT& fPosy, FLOAT& fPosz // 返回建筑物的行走面位置。 ) { FLOAT fDistance = 1000; INT iL = ix - BUILD_COLLISION_SEARCH_RANGE; INT iR = ix + BUILD_COLLISION_SEARCH_RANGE; INT iT = iz - BUILD_COLLISION_SEARCH_RANGE; INT iB = iz + BUILD_COLLISION_SEARCH_RANGE; POINT_2D pos; INT iSize = 0; POINT_3D Orig; // 射线的原点。 POINT_3D Dir; // 射线的方向。 POINT_3D v1; POINT_3D v2; POINT_3D v3; FLOAT fd = 0; FLOAT fv = 0; FLOAT fu = 0; Orig.fx = fOrigx; Orig.fy = fOrigy; Orig.fz = fOrigz; Dir.fx = fDirx; Dir.fy = fDiry; Dir.fz = fDirz; BOOL bReturn = FALSE; for(INT i = iL; i < iR; i++) for(INT j = iT; j < iB; j++) { pos.iX = i; pos.iY = j; if(0 == m_triInfoMap.count(pos)) { continue; } TRI_INFO_VECTOR& triInfo = m_triInfoMap[pos]; iSize = (INT)triInfo.size(); for(INT iRri = 0; iRri < iSize; iRri++) { v1.fx = triInfo[iRri].v1.fx; v1.fy = triInfo[iRri].v1.fy; v1.fz = triInfo[iRri].v1.fz; v2.fx = triInfo[iRri].v2.fx; v2.fy = triInfo[iRri].v2.fy; v2.fz = triInfo[iRri].v2.fz; v3.fx = triInfo[iRri].v3.fx; v3.fy = triInfo[iRri].v3.fy; v3.fz = triInfo[iRri].v3.fz; if(IntersectTriangle(Orig, Dir, v1, v2, v3, &fd, &fu, &fv)) { if(fDistance > fd) { fDistance = fd; fPosx = (1- fv - fu)*v1.fx + fu*v2.fx + fv*v3.fx; fPosy = (1- fv - fu)*v1.fy + fu*v2.fy + fv*v3.fy; fPosz = (1- fv - fu)*v1.fz + fu*v2.fz + fv*v3.fz; } bReturn = true; } }// for(INT iRri = 0; iRri < iSize; i++) } return bReturn; }
v3 GetNormal(const RCONVEXPOLYGONINFO *poly, const rvector &position, int au, int av) { int nSelPolygon = -1, nSelEdge = -1; float fMinDist = FLT_MAX; if (poly->nVertices == 3) nSelPolygon = 0; else { rvector pnormal(poly->plane.a, poly->plane.b, poly->plane.c); for (int i = 0; i < poly->nVertices - 2; i++) { const auto& a = poly->pVertices[0]; const auto& b = poly->pVertices[i + 1]; const auto& c = poly->pVertices[i + 2]; if (IntersectTriangle(a, b, c, position + pnormal, -pnormal, nullptr)) { nSelPolygon = i; nSelEdge = -1; break; } else { float dist = GetDistance(position, a, b); if (dist < fMinDist) { fMinDist = dist; nSelPolygon = i; nSelEdge = 0; } dist = GetDistance(position, b, c); if (dist < fMinDist) { fMinDist = dist; nSelPolygon = i; nSelEdge = 1; } dist = GetDistance(position, c, a); if (dist < fMinDist) { fMinDist = dist; nSelPolygon = i; nSelEdge = 2; } } } } auto& v0 = poly->pVertices[0]; auto& v1 = poly->pVertices[nSelPolygon + 1]; auto& v2 = poly->pVertices[nSelPolygon + 2]; auto& n0 = poly->pNormals[0]; auto& n1 = poly->pNormals[nSelPolygon + 1]; auto& n2 = poly->pNormals[nSelPolygon + 2]; v3 pos; if (nSelEdge != -1) { auto& e0 = nSelEdge == 0 ? v0 : nSelEdge == 1 ? v1 : v2; auto& e1 = nSelEdge == 0 ? v1 : nSelEdge == 1 ? v2 : v0; auto dir = Normalized(e1 - e0); pos = e0 + DotProduct(dir, position - e0) * dir; } else pos = position; auto a = v1 - v0; auto b = v2 - v1; auto x = pos - v0; float f = b[au] * x[av] - b[av] * x[au]; if (IS_ZERO(f)) return n0; float t = (a[av] * x[au] - a[au] * x[av]) / f; auto tem = InterpolatedVector(n1, n2, t); auto inter = a + t*b; int axisfors; if (fabs(inter.x) > fabs(inter.y) && fabs(inter.x) > fabs(inter.z)) axisfors = 0; else if (fabs(inter.y) > fabs(inter.z)) axisfors = 1; else axisfors = 2; float s = x[axisfors] / inter[axisfors]; return InterpolatedVector(n0, tem, s); }
////////////////////////////////////////////////////////////////////////// // Given the position, normal, and set of rays compute the bent normal and // occlusion term. ////////////////////////////////////////////////////////////////////////// void ComputeOcclusion (NmRawPointD* newPos, NmRawPointD* newNorm, int numTris, NmRawTriangle* tri, AtiOctree* octree, int numRays, NmRawPointD* rays, double* rayWeights, NmRawPointD* bentNormal, double* occlusion, int& gMaxCells, AtiOctreeCell** &gCell) { #ifdef _DEBUG if ((newPos == NULL) || (newNorm == NULL) || (tri == NULL) || (octree == NULL) || (rays == NULL) || (rayWeights == NULL) || (bentNormal == NULL) || (occlusion == NULL)) { //NmPrint ("ERROR: Incorrect arguments passed!\n"); exit (-1); } #endif // Clear results. // Bent normal should at minimum be the regular normal (I think). bentNormal->x = newNorm->x; bentNormal->y = newNorm->y; bentNormal->z = newNorm->z; (*occlusion) = 0.0; double hit = 0.0f; double num = 0.0f; // Compute offset vertex NmRawPointD pos; pos.x = newPos->x + (newNorm->x * gDistanceOffset); pos.y = newPos->y + (newNorm->y * gDistanceOffset); pos.z = newPos->z + (newNorm->z * gDistanceOffset); // Compute rotation matrix to match hemisphere to normal double rotMat[16]; FromToRotation (rotMat, gZVec, newNorm->v); // Shoot the rays for (int r = 0; r < numRays; r++) { // First rotate the ray into position NmRawPointD oRay; oRay.x = rays[r].x*rotMat[0] + rays[r].y*rotMat[4] + rays[r].z*rotMat[8]; oRay.y = rays[r].x*rotMat[1] + rays[r].y*rotMat[5] + rays[r].z*rotMat[9]; oRay.z = rays[r].x*rotMat[2] + rays[r].y*rotMat[6] + rays[r].z*rotMat[10]; // Walk the Octree to find triangle intersections. bool intersect = false; int numCells = 0; int cellCount = 0; int triCount = 0; AddCell (octree->m_root, &numCells, gMaxCells, gCell); while ((numCells > 0) && !intersect) { // Take the cell from the list. cellCount++; numCells--; AtiOctreeCell* currCell = gCell[numCells]; // See if this is a leaf node bool leaf = true; for (int c = 0; c < 8; c++) { if (currCell->m_children[c] != NULL) { leaf = false; break; } } // If we are a leaf check the triangles if (leaf) { // Run through the triangles seeing if the ray intersects. for (int t = 0; t < currCell->m_numItems; t++) { // Save off current triangle. NmRawTriangle* currTri = &(tri[currCell->m_item[t]]); triCount++; // See if it intersects. double oT, oU, oV; if (IntersectTriangle (pos.v, oRay.v, currTri->vert[0].v, currTri->vert[1].v, currTri->vert[2].v, &oT, &oU, &oV)) { if (oT > 0.0f) { intersect = true; break; } } } // end for t (num triangles in this cell) } // end if leaf else { // Non-leaf, add the children to the list if their bounding // box intersects the ray. for (int c = 0; c < 8; c++) { if (currCell->m_children[c] != NULL) { // Save off current child. AtiOctreeCell* child = currCell->m_children[c]; // If the ray intersects the box if (RayIntersectsBox (&pos, &oRay, &child->m_boundingBox)) { AddCell (child, &numCells, gMaxCells, gCell); } // end if the ray intersects this bounding box. // else do nothing, we'll never intersect any triangles // for it's children. } // end if we have a cell } // end for c (8 children) } // end else non-leaf node. } // end while cells // Update our running results based on if we found and intersection. num += rayWeights[r]; if (!intersect) { bentNormal->x += (oRay.x * rayWeights[r]); bentNormal->y += (oRay.y * rayWeights[r]); bentNormal->z += (oRay.z * rayWeights[r]); } else { hit += rayWeights[r]; } /* // Save off some stats. if (triCount > gAOMaxTrisTested) { gAOMaxTrisTested = triCount; } if (cellCount > gAOMaxCellsTested) { gAOMaxCellsTested = cellCount; } */ } // end for r (number of rays) // Normalize result Normalize (bentNormal->v); (*occlusion) = (num - hit) / num; } // end of ComputeOcclusion
////////////////////////////////////////////////////////////////////////// // Figure out if we have an intersection from the given point, if we do // make sure it's the "best" one. Returns true if it found an intersection // false otherwise. It places the normal into newNormal and position into // newPos. ////////////////////////////////////////////////////////////////////////// inline bool FindBestIntersection (NmRawPointD& pos, NmRawPointD& norm, AtiOctree* octree, NmRawTriangle* highTris, NmTangentMatrix* hTangentSpace, float* bumpMap, int bumpHeight, int bumpWidth, double newNorm[3], double newPos[3], double* displacement, int gNormalRules, double gMaxAngle, double gDistance, double gEpsilon, int& gMaxCells, AtiOctreeCell** &gCell) { // Clear outputs. newNorm[0] = 0.0; newNorm[1] = 0.0; newNorm[2] = 0.0; newPos[0] = 0.0; newPos[1] = 0.0; newPos[2] = 0.0; // Create negative normal NmRawPointD negNorm; negNorm.x = -norm.x; negNorm.y = -norm.y; negNorm.z = -norm.z; // Some stats. int cellCount = 0; int hitTriCount = 0; int triCount = 0; // Walk the octree looking for intersections. NmRawPointD intersect; NmRawPointD lastIntersect; int numCells = 0; AddCell (octree->m_root, &numCells, gMaxCells, gCell); while (numCells > 0) { // Take the cell from the list. cellCount++; numCells--; AtiOctreeCell* currCell = gCell[numCells]; // See if this is a leaf node bool leaf = true; for (int c = 0; c < 8; c++) { if (currCell->m_children[c] != NULL) { leaf = false; break; } } // If we are a leaf check the triangles if (leaf) { // Run through the triangles seeing if the ray intersects. for (int t = 0; t < currCell->m_numItems; t++) { // Save off current triangle. NmRawTriangle* hTri = &highTris[currCell->m_item[t]]; // See if it intersects. triCount++; if (IntersectTriangle (pos.v, norm.v, hTri->vert[0].v, hTri->vert[1].v, hTri->vert[2].v, &intersect.x, &intersect.y, &intersect.z)) { // Keep some statistics. hitTriCount++; // Figure out new normal and position double b0 = 1.0 - intersect.y - intersect.z; double np[3]; double nn[3]; BaryInterpolate (hTri, b0, intersect.y, intersect.z, np, nn); // Debug this intersection test if requested. // See if this should be the normal for the map. if (IntersectionIsBetter (gNormalRules, &norm, nn, &intersect, newNorm, &lastIntersect, gMaxAngle, gDistance, gEpsilon)) { // Perturb by bump map if (bumpMap != NULL) { GetPerturbedNormal (hTri, b0, intersect.y, intersect.z, bumpMap, bumpWidth, bumpHeight, hTangentSpace[currCell->m_item[t]].m, nn); } // Copy over values memcpy (newNorm, nn, sizeof (double)*3); memcpy (newPos, np, sizeof (double)*3); memcpy (&lastIntersect, &intersect, sizeof (NmRawPointD)); } // end if this intersection is better #ifdef DEBUG_INTERSECTION else if (gDbgIntersection) { NmPrint (" <<< Intersection is worse!\n"); } #endif } // end if we have an intersection } // end for t (num triangles in this cell) } // end if leaf else { // Non-leaf, add the children to the list if their bounding // box intersects the ray. for (int c = 0; c < 8; c++) { if (currCell->m_children[c] != NULL) { // Save off current child. AtiOctreeCell* child = currCell->m_children[c]; // If the ray intersects the box if (RayIntersectsBox (&pos, &norm, &child->m_boundingBox)) { AddCell (child, &numCells, gMaxCells, gCell); } // end if the ray intersects this bounding box. else if (RayIntersectsBox (&pos, &negNorm, &child->m_boundingBox)) { AddCell (child, &numCells, gMaxCells, gCell); } // end if the ray intersects this bounding box. // else do nothing, we'll never intersect any triangles // for it's children. } // end if we have a cell } // end for c (8 children) } // end else non-leaf node. } // end while cells /* // Save off some stats. if (triCount > gMaxTrisTested) { gMaxTrisTested = triCount; } if (hitTriCount > gMaxTrisHit) { gMaxTrisHit = hitTriCount; } if (cellCount > gMaxCellsTested) { gMaxCellsTested = cellCount; } */ // Test if we found an intersection. if ( (newNorm[0] != 0.0) || (newNorm[1] != 0.0) || (newNorm[2] != 0.0) ) { (*displacement) = lastIntersect.x; return true; } return false; } // end of FindBestIntersection
bool CObject3D::Pick(const D3DXMATRIX& world, const D3DXVECTOR3& origin, const D3DXVECTOR3& dir, float& dist) { #ifdef WORLD_EDITOR float tempDist; bool pick = false; dist = 65535.0f; D3DXMATRIX invTM, TM; D3DXVECTOR3 invOrigin, invDir; GMObject* obj; ushort* IB, *IIB; int faceCount, i, j, boneID; D3DXMATRIX* bones, *invBones; for (i = 0; i < m_groups[0].objectCount; i++) { obj = &m_groups[0].objects[i]; if (obj->type == GMT_SKIN) { D3DXMatrixInverse(&invTM, null, &world); D3DXVec3TransformCoord(&invOrigin, &origin, &invTM); invTM._41 = 0; invTM._42 = 0; invTM._43 = 0; D3DXVec3TransformCoord(&invDir, &dir, &invTM); const SkinVertex* VB = (SkinVertex*)obj->vertices; IB = obj->indices; faceCount = obj->faceListCount; IIB = obj->IIB; if (m_externBones) { bones = m_externBones; invBones = m_externInvBones; } else { bones = m_baseBones; invBones = m_baseInvBones; } const int vertexCount = obj->vertexCount; if (vertexCount > 4096) continue; const int* physique = obj->physiqueVertices; static D3DXVECTOR3 temp[4096]; for (j = 0; j < vertexCount; j++) { boneID = physique[*IIB++]; TM = invBones[boneID] * bones[boneID]; D3DXVec3TransformCoord(&temp[j], &VB[j].p, &TM); } for (j = 0; j < faceCount; j++) { const D3DXVECTOR3& v1 = temp[*IB++]; const D3DXVECTOR3& v2 = temp[*IB++]; const D3DXVECTOR3& v3 = temp[*IB++]; if (IntersectTriangle(v1, v2, v3, invOrigin, invDir, tempDist) && tempDist < dist) { pick = true; dist = tempDist; } } } else { if (m_groups[0].updates) { TM = m_groups[0].updates[i] * world; D3DXMatrixInverse(&invTM, null, &TM); D3DXVec3TransformCoord(&invOrigin, &origin, &invTM); invTM._41 = 0; invTM._42 = 0; invTM._43 = 0; D3DXVec3TransformCoord(&invDir, &dir, &invTM); const NormalVertex* VB = (NormalVertex*)obj->vertices; IB = obj->indices; faceCount = obj->faceListCount; for (j = 0; j < faceCount; j++) { const D3DXVECTOR3& v1 = VB[*IB++].p; const D3DXVECTOR3& v2 = VB[*IB++].p; const D3DXVECTOR3& v3 = VB[*IB++].p; if (IntersectTriangle(v1, v2, v3, invOrigin, invDir, tempDist) && tempDist < dist) { pick = true; dist = tempDist; } } } } } return pick; #else // WORLD_EDITOR return false; #endif // WORLD_EDITOR }
bool RayTesselatedTrianglePrimitive::Intersect(const Ray& ray) { Vec3f v0, v1, v2; _ResolveVertexAttrib(v0,v1,v2,triangles->pos); float t, b1, b2, rayEpsilon; return IntersectTriangle(v0,v1,v2,ray, &t, &b1, &b2, &rayEpsilon); }