public static void BuildRay(ref List <BVHRay> rayList, ref List <BVHObject> triObjects) { BVHIntersectionInfo info = new BVHIntersectionInfo(); for (int i = 0; i < triObjects.Count; ++i) { Vector3 pos = triObjects[i].GetCentroid(); BVHRay ray = new BVHRay(new Vector3(pos.x, 0.0f, pos.z), Vector3.up); rayList.Add(ray); } }
public bool GetIntersection(ref BVHRay ray, ref BVHIntersectionInfo intersection) { float near = 0.0f; float far = 0.0f; bool isect = mAABB.Intersect(ray, ref near, ref far); if (isect) { intersection.mObject = this; intersection.mHitPoint = ray.mOrigin + ray.mDirection * near; intersection.mLength = near; } return(isect); }
public bool GetIntersection(ref BVHRay ray, ref BVHIntersectionInfo intersection) { Vector3 s = mCenter - ray.mOrigin; float sd = Vector3.Dot(s, ray.mDirection); float ss = s.magnitude * s.magnitude; float disc = sd * sd + mRadius2 - ss; if (disc < 0.0f) { return(false); } intersection.mObject = this; intersection.mLength = sd - Mathf.Sqrt(disc); return(true); }
public abstract bool GetIntersection(ref BVHRay ray, ref BVHIntersectionInfo intersection);
public bool Intersect(BVHRay ray, ref float dnear, ref float dfar) { // Intermediate calculation variables. float tmin = 0.0f; float tmax = 0.0f; // X direction. float div = ray.mInvDirection.x; if (div >= 0.0f) { tmin = (mMin.x - ray.mOrigin.x) * div; tmax = (mMax.x - ray.mOrigin.x) * div; } else { tmin = (mMax.x - ray.mOrigin.x) * div; tmax = (mMin.x - ray.mOrigin.x) * div; } dnear = tmin; dfar = tmax; // Check if the ray misses the box. if (dnear > dfar || dfar < 0.0f) { return(false); } // Y direction. div = ray.mInvDirection.y; if (div >= 0.0f) { tmin = (mMin.y - ray.mOrigin.y) * div; tmax = (mMax.y - ray.mOrigin.y) * div; } else { tmin = (mMax.y - ray.mOrigin.y) * div; tmax = (mMin.y - ray.mOrigin.y) * div; } // Update the near and far intersection distances. if (tmin > dnear) { dnear = tmin; } if (tmax < dfar) { dfar = tmax; } // Check if the ray misses the box. if (dnear > dfar || dfar < 0.0f) { return(false); } // Z direction. div = ray.mInvDirection.z; if (div >= 0.0f) { tmin = (mMin.z - ray.mOrigin.z) * div; tmax = (mMax.z - ray.mOrigin.z) * div; } else { tmin = (mMax.z - ray.mOrigin.z) * div; tmax = (mMin.z - ray.mOrigin.z) * div; } // Update the near and far intersection distances. if (tmin > dnear) { dnear = tmin; } if (tmax < dfar) { dfar = tmax; } // Check if the ray misses the box. if (dnear > dfar || dfar < 0.0f) { return(false); } return(true); }
public bool GetIntersection(ref BVHRay ray, ref BVHIntersectionInfo intersection) { Vector3 edge1, edge2, tvec, pvec, qvec; double det, inv_det; double t; //find vectors for two edges sharing vert0 edge1 = mP2 - mP1; edge2 = mP3 - mP1; // begin calculating determinant - also used to calculate U parameter pvec = Vector3.Cross(ray.mDirection, edge2); // if determinant is near zero, ray lies in plane of triangle det = Vector3.Dot(edge1, pvec); #if TEST_CULL // define TEST_CULL if culling is desired if (det < 1e-5f) { return(false); } tvec = ray.mOrigin - mP1; // calculate U parameter and test bounds double u = Vector3.Dot(tvec, pvec); if (u < 0.0 || u > det) { return(false); } // prepare to test V parameter qvec = Vector3.Cross(tvec, edge1); // calculate V parameter and test bounds double v = Vector3.Dot(ray.mDirection, qvec); if (v < 0.0 || u + v > det) { return(false); } // calculate t, scale parameters, ray intersects triangle t = Vector3.Dot(edge2, qvec); inv_det = 1.0 / det; t *= inv_det; u *= inv_det; v *= inv_det; #else // the non-culling branch if (det > -1e-5f && det < 1e-5f) { return(false); } inv_det = 1.0 / det; // calculate distance from vert0 to ray origin tvec = ray.mOrigin - mP1; // calculate U parameter and test bounds double u = Vector3.Dot(tvec, pvec) * inv_det; if (u < 0.0 || u > 1.0) { return(false); } // prepare to test V parameters qvec = Vector3.Cross(tvec, edge1); // calculate V paremeter and test bounds double v = Vector3.Dot(ray.mDirection, qvec) * inv_det; if (v < 0.0 || u + v > 1.0) { return(false); } //calculate t, ray intersects triangle t = Vector3.Dot(edge2, qvec) * inv_det; #endif intersection.mLength = (float)t; intersection.mObject = this; return(true); }
/// <summary> /// /// </summary> /// <param name="ray">射线</param> /// <param name="intersection">交点信息</param> /// <param name="occlusion">是否找到最短的。 true if 找到交叉就行; false if 找到最短的 </param> /// <returns></returns> public bool GetIntersection(BVHRay ray, ref BVHIntersectionInfo intersection, bool occlusion) { intersection.mLength = 999999999.0f; intersection.mObject = null; float[] bbhits = new float[4]; int closer, other; BVHTraversal[] todo = new BVHTraversal[64]; todo[0] = new BVHTraversal(); int stackptr = 0; todo[stackptr].mIndex = 0; todo[stackptr].mLength = -9999999.0f; while (stackptr >= 0) { int ni = todo[stackptr].mIndex; float near = todo[stackptr].mLength; stackptr--; BVHFlatNode node = mFlatTreeList[ni]; if (near > intersection.mLength) { continue; } // 对叶节点做相交测试 if (node.mRightOffset == 0) { bool hit = false; for (int o = 0; o < node.mLeafCount; ++o) { BVHIntersectionInfo current = new BVHIntersectionInfo(); BVHObject obj = mBuildPrims[(int)node.mStartIndex + o]; hit = obj.GetIntersection(ref ray, ref current); if (hit) { if (occlusion) { return(true); } if (current.mLength < intersection.mLength) { intersection = current; } } } } else { // 对父结点做测试 bool hitc0 = mFlatTreeList[ni + 1].mBox.Intersect(ray, ref bbhits[0], ref bbhits[1]); bool hitc1 = mFlatTreeList[ni + (int)node.mRightOffset].mBox.Intersect(ray, ref bbhits[2], ref bbhits[3]); if (hitc0 && hitc1) { closer = ni + 1; other = ni + (int)node.mRightOffset; if (bbhits[2] < bbhits[0]) { float temp = bbhits[0]; bbhits[0] = bbhits[2]; bbhits[2] = temp; temp = bbhits[1]; bbhits[1] = bbhits[3]; bbhits[3] = temp; int itemp = closer; closer = other; other = itemp; } todo[++stackptr] = new BVHTraversal(other, bbhits[2]); todo[++stackptr] = new BVHTraversal(closer, bbhits[0]); } else if (hitc0) { todo[++stackptr] = new BVHTraversal(ni + 1, bbhits[0]); } else if (hitc1) { todo[++stackptr] = new BVHTraversal(ni + (int)node.mRightOffset, bbhits[2]); } } } if (intersection.mObject != null) { intersection.mHitPoint = ray.mOrigin + ray.mDirection * intersection.mLength; } return(intersection.mObject != null); }