public static void TestBVH() { List <BVHObject> triObjects = new List <BVHObject>(); BuildTriangles(ref triObjects); List <BVHRay> rayList = new List <BVHRay>(); BuildRay(ref rayList, ref triObjects); float start = Time.realtimeSinceStartup; BVH bvh = new BVH(triObjects); float end1 = Time.realtimeSinceStartup; Debug.Log(string.Format("time initialized: {0}", end1 - start)); BVHIntersectionInfo insect = new BVHIntersectionInfo(); int insectC = 0; int missC = 0; for (int i = 0; i < 200; ++i) { foreach (BVHRay ray in rayList) { int test = bvh.GetIntersection(ray, ref insect, false) ? insectC++ : missC++; } } float end2 = Time.realtimeSinceStartup; Debug.Log(string.Format("time slapped: {0}, insect: {1}, miss: {2}", end2 - end1, insectC, missC)); }
public Vector3 GetNormal(ref BVHIntersectionInfo i) { Vector3 nor = i.mHitPoint - mCenter; nor.Normalize(); return(nor); }
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 Vector3 GetNormal(ref BVHIntersectionInfo i) { Vector3 v = i.mHitPoint - mAABB.mMin; if (v.x == 0.0f || v.y == 0.0f || v.z == 0.0f) { if (v.x == 0.0f) { return(Vector3.left); } else if (v.y == 0.0f) { return(Vector3.down); } else if (v.z == 0.0f) { return(Vector3.back); } } else { if (v.x == 0.0f) { return(Vector3.right); } else if (v.y == 0.0f) { return(Vector3.up); } else if (v.z == 0.0f) { return(Vector3.forward); } } // won't be exist return(Vector3.zero); }
public abstract Vector3 GetNormal(ref BVHIntersectionInfo i);
public abstract bool GetIntersection(ref BVHRay ray, ref BVHIntersectionInfo intersection);
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); }
public Vector3 GetNormal(ref BVHIntersectionInfo i) { return(mNormal); }
/// <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); }