/// <summary> /// Create collision polygon /// </summary> /// <param name="offset">Offset</param> /// <param name="vert_indx">Vert _indx</param> /// <param name="vert_offset">Vert _offset</param> /// <param name="vertexPositions">Vert _pos</param> public CollisionPolygon(int offset, int[] vert_indx, int vert_offset, Vector3[] vertexPositions) { vertexIndices = new int[3]; box = new BoxHelper(float.MaxValue, -float.MaxValue); for (int i = 0; i < 3; i++) { vertexIndices[i] = vert_indx[i + offset] + vert_offset; box.AddPoint(vertexPositions[vertexIndices[i]]); } // for (int) }
/// <summary> /// Point intersect /// </summary> /// <param name="ray">Ray</param> /// <param name="vertexPositions">Vertex positions</param> /// <param name="distance">Distance</param> /// <param name="collisionPosition">Collision position</param> /// <param name="collisionNormal">Collision normal</param> /// <returns>Bool</returns> public bool DoesRayIntersect(Ray ray, Vector3[] vertexPositions, out float distance, out Vector3 collisionPosition, out Vector3 collisionNormal) { distance = 0.0f; collisionPosition = ray.origin; collisionNormal = Vector3.Zero; if (ray.Length == 0) return false; BoxHelper rayBox = new BoxHelper(float.MaxValue, -float.MaxValue); rayBox.AddPoint(ray.origin); rayBox.AddPoint(ray.EndPosition); Vector3 inflate = new Vector3(0.001f, 0.001f, 0.001f); rayBox.min -= inflate; rayBox.max += inflate; List<BaseCollisionObject> elems = new List<BaseCollisionObject>(); root.GetElements(rayBox, elems, ++id); ray.direction *= 1.0f / ray.Length; distance = ray.Length; bool intersected = false; foreach (BaseCollisionObject collisionObject in elems) { float checkDistance; Vector3 position; Vector3 normal; if (true == collisionObject.DoesRayIntersect(ray, vertexPositions, out checkDistance, out position, out normal)) { if (checkDistance < distance) { distance = checkDistance; collisionPosition = position; collisionNormal = normal; intersected = true; } // if (checkDistance) } // if (true) } // foreach (collisionObject) return intersected; }
/// <summary> /// Load mesh, must be called after we got all bones. Will also create /// the vertex and index buffers and optimize the vertices as much as /// we can. /// </summary> /// <param name="colladaFile">Collada file</param> private void LoadMesh(XmlNode colladaFile) { XmlNode geometrys = XmlHelper.GetChildNode(colladaFile, "library_geometries"); if (geometrys == null) throw new InvalidOperationException( "library_geometries node not found in collision file"); foreach (XmlNode geometry in geometrys) if (geometry.Name == "geometry") { // Load everything from the mesh node LoadMeshGeometry(colladaFile, XmlHelper.GetChildNode(colladaFile, "mesh"), XmlHelper.GetXmlAttribute(geometry, "name")); // Optimize vertices first and build index buffer from that! indices = OptimizeVertexBuffer(); // Copy and create everything to CollisionFace faces = new CollisionPolygon[indices.Length / 3]; for (int i = 0; i < indices.Length / 3; i++) { faces[i] = new CollisionPolygon(i * 3, indices, 0, vectors); } // for (int) BoxHelper box = new BoxHelper(float.MaxValue, -float.MaxValue); for (int i = 0; i < vectors.Length; i++) box.AddPoint(vectors[i]); uint subdivLevel = 4; // max 8^6 nodes tree = new CollisionHelper(box, subdivLevel); for (int i = 0; i < faces.Length; i++) tree.AddElement(faces[i]); // Get outa here, we currently only support one single mesh! return; } // foreach if (geometry.Name) }