public IntersectionData() { hitT = double.MaxValue; hitPos = new Vector3(); hitNormal = new Vector3(); hitUV = new Vector3(); hitPrimitive = null; hasIntersection = false; textureUVW = new Vector3(); shaderID = 0; }
public void GetIntersection( Vector3 rayOrigin, Vector3 rayDirection, GeomPrimitive lastHit, out GeomPrimitive pHitObject, Vector3 pStart, RayContext rayContext) { //hitPosition = null; pHitObject = null; // is branch: step through subcells and recurse if (isBranch) { //if (pStart == null) // pStart = rayOrigin; // find which subcell holds ray origin (ray origin is inside cell) int subCell = 0; for (int i = 3; i-- > 0; ) { // compare dimension with center if (pStart[i] >= ((bound[i] + bound[i + 3]) * 0.5f)) subCell |= 1 << i; } // step through intersected subcells Vector3 cellPosition = new Vector3(pStart); for (; ; ) { if (null != spatial[subCell]) { // intersect subcell spatial[subCell].GetIntersection(rayOrigin, rayDirection, lastHit, out pHitObject, cellPosition, rayContext); // exit if item hit if (null != pHitObject) break; } // find next subcell ray moves to // (by finding which face of the corner ahead is crossed first) int axis = 2; float[] step = new float[3]; // todo - move this allocation? for (int i = 3; i-- > 0; axis = step[i] < step[axis] ? i : axis) { bool high = ((subCell >> i) & 1) != 0; float face = (rayDirection[i] < 0.0f) ^ high ? bound[i + ((high ? 1 : 0) * 3)] : (bound[i] + bound[i + 3]) * 0.5f; // distance to face // (div by zero produces infinity, which is later discarded) step[i] = (float)(face - rayOrigin[i]) / (float)rayDirection[i]; } // leaving branch if: subcell is low and direction is negative, // or subcell is high and direction is positive if ((((subCell >> axis) & 1) != 0) ^ (rayDirection[axis] < 0.0f)) break; // move to (outer face of) next subcell cellPosition = rayOrigin + (rayDirection * step[axis]); subCell = subCell ^ (1 << axis); } } else { // is leaf: exhaustively intersect contained items //float nearestDistance = float.MaxValue; // step through items foreach (GeomPrimitive item in triangles) { if (rayContext.ignorePrimitive == item) continue; //skip this primitive if (item == lastHit) continue; //skip this primitive IntersectionData hitData = new IntersectionData(); if (item.intersect(rayContext.ray, hitData)) { // check intersection is inside cell bound (with tolerance) Vector3 hit = rayOrigin + (rayDirection * hitData.hitT); float t = TOLERANCE; if ((bound[0] - hit[0] <= t) && (hit[0] - bound[3] <= t) && (bound[1] - hit[1] <= t) && (hit[1] - bound[4] <= t) && (bound[2] - hit[2] <= t) && (hit[2] - bound[5] <= t)) { pHitObject = item; //nearestDistance = distance; //hitPosition = hit; rayContext.hitData = hitData; rayContext.hitData.hitPrimitive = item; rayContext.hitData.hitPos = rayContext.ray.p + rayContext.ray.dir * rayContext.hitData.hitT; rayContext.hitData.hasIntersection = true; } } } } }
public void removePrimitive(GeomPrimitive primitive) { primitives.Remove(primitive); }
public void addPrimitive(GeomPrimitive primitive) { primitives.Add(primitive); }