public bool trace_triangle(ref Vector3 v0, ref Vector3 v1, ref Vector3 v2, ref Vector3 src, ref Vector3 dir, ref DxTraceInfo result, ref bool hitted) { float t = 0; float u = 0; float v = 0; // 射线与三角形相交 if (VisUtil_IntersectTri(ref v0, ref v1, ref v2, ref src, ref dir, ref u, ref v, ref t)) { if ((t >= 0.0f) && (t <= 1.0f)) { if (result.nHitMax > 1) { if (result.nHitCount >= result.nHitMax) { return(false); } hitted = true; if (t < result.fDistance) { // 距离最近的碰撞点 result.fDistance = t; } DxTraceInfo.hit_t pHit = result.Hits[result.nHitCount]; pHit.fDistance = t; pHit.fTraceU = u; pHit.fTraceV = v; // 设置为地形对象 pHit.TraceID = new PERSISTID(0); pHit.nMaterialIndex = 0; pHit.Vertex[0] = v0; pHit.Vertex[1] = v1; pHit.Vertex[2] = v2; pHit.strTexName = ""; if (++result.nHitCount >= result.nHitMax) { return(false); } } else if (t < result.fDistance) { hitted = true; // 距离最近的碰撞点 result.fDistance = t; DxTraceInfo.hit_t pHit = result.Hits[0]; pHit.fDistance = t; pHit.fTraceU = u; pHit.fTraceV = v; // 设置为地形对象 pHit.TraceID = new PERSISTID(0); pHit.nMaterialIndex = 0; pHit.Vertex[0] = v0; pHit.Vertex[1] = v1; pHit.Vertex[2] = v2; pHit.strTexName = ""; result.nHitCount = 1; } } } return(true); }
// 碰撞测试详细信息实现 public bool TraceDetail(ref D3DXVECTOR3 src, ref D3DXVECTOR3 dst, ref DxTraceInfo result) { Vector3 _src; _src.x = src.x; _src.y = src.y; _src.z = src.z; Vector3 _dst; _dst.x = dst.x; _dst.y = dst.y; _dst.z = dst.z; float dis = Vector3.Distance(_src, _dst); if (dis <= 0) { return(false); } RaycastHit[] hits = new RaycastHit[result.nHitMax]; if (!game_obj.TraceDetail(_src, _dst, ref hits, ref result.nHitCount)) { return(false); } Vector3 origin = _dst - _src; //RaycastHit 转换成 DxTraceInfo result.fDistance = 1e8f; for (int i = 0; i < result.nHitCount; ++i) { RaycastHit hit = hits[i]; result.Hits[i].fDistance = hit.distance / dis; if (result.fDistance > result.Hits[i].fDistance) { result.fDistance = result.Hits[i].fDistance; } if ((hit.collider && hit.collider.gameObject) && (Terrain.activeTerrain.gameObject == hit.collider.gameObject)) { result.Hits[i].TraceID = new PERSISTID(0); } else { result.Hits[i].TraceID = new PERSISTID(1); } result.Hits[i].nMaterialIndex = 0; result.Hits[i].strTexName = ""; if (hit.normal.y != 0.0f) { Vector3 p = hit.point + hit.normal; float y = (Vector3.Dot(hit.normal, hit.point) - hit.normal.x * p.x - hit.normal.z * p.z) / hit.normal.y; Vector3 p1 = new Vector3(p.x, y, p.z); Vector3 n = Vector3.Cross(hit.normal, p1); Vector3 p2 = n + hit.point; result.Hits[i].Vertex[0] = hit.point; result.Hits[i].Vertex[1] = p1; result.Hits[i].Vertex[2] = p2; result.Hits[i].fTraceU = 0.0f; result.Hits[i].fTraceV = 0.0f; continue; } if (hit.normal.x != 0.0f) { Vector3 p = hit.point + hit.normal; float x = (Vector3.Dot(hit.normal, hit.point) - hit.normal.y * p.y - hit.normal.z * p.z) / hit.normal.x; Vector3 p1 = new Vector3(x, p.y, p.z); Vector3 n = Vector3.Cross(hit.normal, p1); Vector3 p2 = n + hit.point; result.Hits[i].Vertex[0] = hit.point; result.Hits[i].Vertex[1] = p1; result.Hits[i].Vertex[2] = p2; result.Hits[i].fTraceU = 0.0f; result.Hits[i].fTraceV = 0.0f; continue; } if (hit.normal.z != 0.0f) { Vector3 p = hit.point + hit.normal; float z = (Vector3.Dot(hit.normal, hit.point) - hit.normal.x * p.x - hit.normal.y * p.y) / hit.normal.z; Vector3 p1 = new Vector3(p.x, p.y, z); Vector3 n = Vector3.Cross(hit.normal, p1); Vector3 p2 = n + hit.point; result.Hits[i].Vertex[0] = hit.point; result.Hits[i].Vertex[1] = p1; result.Hits[i].Vertex[2] = p2; result.Hits[i].fTraceU = 0.0f; result.Hits[i].fTraceV = 0.0f; continue; } } return(true); }