/// <summary> /// Returns the shortest path from source to destination /// using A* algorithm. /// </summary> /// <param name='src' type='GameObject'> /// Source. /// </param> /// <param name='dst' type='GameObject'> /// Destination /// </param> public List <GameObject> Astar(GameObject src, GameObject dst) { List <AiEdge> successors; AiVertex auxVertex; int cost = 0; bool isInFrontier = false, isInExplored = false; AiNode node = new AiNode(src, 1); AiNode dstNode = new AiNode(dst, 1); AiNode child; GPWiki.BinaryHeap <AiNode> frontier = new GPWiki.BinaryHeap <AiNode>(); List <GameObject> explored = new List <GameObject>(); frontier.Add(node); while (true) { if (frontier.Count == 0) { return(new List <GameObject>()); } node = frontier.Remove(); explored.Add(node.m_GameObject); if (node.Equals(dstNode)) { return(explored); } auxVertex = node.m_GameObject.GetComponent <AiVertex>(); successors = auxVertex.m_Successors; foreach (AiEdge e in successors) { cost = e.m_Cost; cost += (int)Vector3.Distance(e.m_Vertex.gameObject.transform.position, dst.transform.position); child = new AiNode(e.m_Vertex.gameObject, cost); isInFrontier = frontier.Contains(child); isInExplored = explored.Contains(child.m_GameObject); if (!isInExplored && !isInFrontier) { frontier.Add(child); } else if (isInFrontier) { foreach (AiNode n in frontier) { if (n.Equals(child) && (n.m_Cost > child.m_Cost)) { frontier.Remove(child); frontier.Add(child); } } } } } }
void Recurse(Transform parent, AiNode node) { //Debug.Log("node name: " + node.Name); //Debug.Log("numchildren: " + node.NumChildren); Transform tr; if (node.Transformation.IsIdentity && node.NumMeshes == 0 && node.NumChildren == 1) { tr = parent; /* skip this intermediate level */ } else { tr = new GameObject(node.Name.GetString()).transform; tr.SetParent(parent); Assimp.Vector3D scale, translation; Assimp.Quaternion rotation; node.Transformation.Decompose(out scale, out rotation, out translation); tr.localPosition = ToVector3(translation); tr.localRotation = ToQuaternion(rotation); tr.localScale = ToVector3(scale); int mesh_i = 0; foreach (var mesh_index in ReadArrayInt(node.Meshes, node.NumMeshes)) { var tr1 = new GameObject("mesh " + mesh_index).transform; tr1.SetParent(tr); tr1.localPosition = Vector3.zero; tr1.localRotation = Quaternion.identity; tr1.localScale = Vector3.one; tr1.gameObject.AddComponent <MeshFilter>().sharedMesh = meshes[mesh_index]; tr1.gameObject.AddComponent <MeshRenderer>().sharedMaterial = mesh2mat[mesh_index]; mesh_i++; } } foreach (var child in ReadArrayOfPtr <AiNode>(node.Children, node.NumChildren)) { Recurse(tr, child); } }
private string ResetPaths(string[] args) { if (path != null) { foreach (AiNode aiNode in path) { if (aiNode.Walkable) { aiNode.Owner.RemoveComponent <MeshRendererComponent>(); } } path.Clear(); } Random rnd = new Random(); AiNode startNode = nodes[rnd.Next(0, 64), rnd.Next(0, 64)]; AiNode endNode = nodes[rnd.Next(0, 64), rnd.Next(0, 64)]; while (!startNode.Walkable) { startNode = nodes[rnd.Next(0, 64), rnd.Next(0, 64)]; } while (!endNode.Walkable) { endNode = nodes[rnd.Next(0, 64), rnd.Next(0, 64)]; } path = AStarResolver.FindPath(startNode, endNode, out bool found); for (int i = 0; i < path.Count; i++) { path[i].Owner .AddComponent(new LitMeshRendererComponent(DefaultFilepaths.DefaultLitShader, Prefabs.Cube, tex, 1)); } startNode.Owner.GetComponent <LitMeshRendererComponent>().Textures[0] = beginTex; endNode.Owner.GetComponent <LitMeshRendererComponent>().Textures[0] = endTex; return("Success: " + found); }
private AiNode[,] GenerateNodeGraph(int width, int length) { AiNode[,] nodes = new AiNode[width, length]; for (int i = 0; i < width; i++) { for (int j = 0; j < length; j++) { GameObject obj = new GameObject("NodeW" + i + "L:" + j) { LocalPosition = new Byt3.Engine.Physics.BEPUutilities.Vector3(i - width / 2, 0, -j) }; AiNode node = new AiNode(true); obj.AddComponent(node); nodes[i, j] = node; } } for (int i = 0; i < width; i++) { for (int j = 0; j < length; j++) { AiNode current = nodes[i, j]; for (int k = -1; k <= 1; k++) { for (int s = -1; s <= 1; s++) { if (i + k < 0 || i + k >= width || j + s < 0 || j + s >= length || k == 0 && s == 0) { continue; } current.AddConnection(nodes[i + k, j + s]); } } } } return(nodes); }
private AiNode[,] GenerateNodeGraph(int width, int length) { AiNode[,] nodes = new AiNode[width, length]; for (int i = 0; i < width; i++) { for (int j = 0; j < length; j++) { AiNode node = new AiNode(true); //Just Filling the map nodes[i, j] = node; } } //Connecting Every node with its surrounding nodes including diagonals // N N N // N 0 N // N N N for (int i = 0; i < width; i++) { for (int j = 0; j < length; j++) { AiNode current = nodes[i, j]; for (int k = -1; k <= 1; k++) { for (int s = -1; s <= 1; s++) { if (i + k < 0 || i + k >= width || j + s < 0 || j + s >= length || k == 0 && s == 0) { continue; } current.AddConnection(nodes[i + k, j + s]); } } } } return(nodes); }
private static void ReadNodeHeirarchy(float animationTime, AiNode node, AiAnimation animation, mat4 parentTransform, AllBoneInfos allBoneInfos) { string nodeName = node.Name; mat4 nodeTransform = node.Transform.ToMat4(); AiNodeAnimationChannel nodeAnim = FineNodeAnim(animation, nodeName); if (nodeAnim != null) { mat4 mat = mat4.identity(); // Interpolate scaling and generate scaling transformation matrix vec3 scaling = CalcInterpolatedScaling(animationTime, nodeAnim); mat4 scalingMat = glm.scale(mat, new vec3(scaling.X, scaling.Y, scaling.Z)); // Interpolate rotation and generate rotation transformation matrix Quaternion rotation = CalcInterpolatedRotation(animationTime, nodeAnim); mat4 rotationMat = new AiMatrix4x4(rotation.GetMatrix()).ToMat4(); // Interpolate translation and generate translation transformation matrix vec3 translation = CalcInterpolatedPosition(animationTime, nodeAnim); mat4 translationMat = glm.translate(mat4.identity(), new vec3(translation.X, translation.Y, translation.Z)); // Combine the above transformations nodeTransform = translationMat * rotationMat * scalingMat; } mat4 globalTransformation = parentTransform * nodeTransform; if (allBoneInfos.nameIndexDict.ContainsKey(nodeName)) { uint BoneIndex = allBoneInfos.nameIndexDict[nodeName]; allBoneInfos.boneInfos[BoneIndex].finalTransformation = globalTransformation * allBoneInfos.boneInfos[BoneIndex].bone.OffsetMatrix.ToMat4(); } for (int i = 0; i < node.ChildCount; i++) { ReadNodeHeirarchy(animationTime, node.Children[i], animation, globalTransformation, allBoneInfos); } }
protected override void Update(float deltaTime) { if (ObjectUnderMouse(Owner.LocalPosition, out KeyValuePair <Collider, RayHit> hit) ) //We Check where we clicked on { AiNode node = hit.Key.Owner.GetComponent <AiNode>(); if (node != null) { if (Input.GetKey(Key.S)) //Setting the Start Point { LitMeshRendererComponent lmr = node.Owner.GetComponent <LitMeshRendererComponent>(); ApplyTexture(lmr, purpleTex); if (startNode != null && startNode != node) { ApplyTexture(startNode.Owner.GetComponent <LitMeshRendererComponent>(), startNode.Walkable ? greenTex : redTex); } startNode = node; } else if (Input.GetKey(Key.E)) //Setting the End Point { LitMeshRendererComponent lmr = node.Owner.GetComponent <LitMeshRendererComponent>(); ApplyTexture(lmr, purpleTex); if (endNode != null && endNode != node) { ApplyTexture(endNode.Owner.GetComponent <LitMeshRendererComponent>(), endNode.Walkable ? greenTex : redTex); } endNode = node; } } } //When Start and end Point is defined and space is pressed we calculate the path if (startNode != null && endNode != null && Input.GetKey(Key.Space)) { if (path != null) //First Clean the Old path, and reset the textures { for (int i = 0; i < path.Count; i++) { LitMeshRendererComponent lmr = (path[i] as AiNode).Owner.GetComponent <LitMeshRendererComponent>(); ApplyTexture(lmr, path[i].Walkable ? greenTex : redTex); } } //This line is doing the A* path = AStarResolver.FindPath(startNode, endNode, out bool foundPath); if (foundPath) //If there exists a path from start to end, we will make it visible { for (int i = 0; i < path.Count; i++) { LitMeshRendererComponent lmr = (path[i] as AiNode).Owner.GetComponent <LitMeshRendererComponent>(); ApplyTexture(lmr, purpleTex); } } } //Escape Resets the Nodes color and removes the starting points if (Input.GetKey(Key.Escape)) { if (startNode != null) { ApplyTexture(startNode.Owner.GetComponent <LitMeshRendererComponent>(), startNode.Walkable ? greenTex : redTex); } if (endNode != null) { ApplyTexture(endNode.Owner.GetComponent <LitMeshRendererComponent>(), endNode.Walkable ? greenTex : redTex); } startNode = endNode = null; if (path != null) { for (int i = 0; i < path.Count; i++) { LitMeshRendererComponent lmr = (path[i] as AiNode).Owner.GetComponent <LitMeshRendererComponent>(); ApplyTexture(lmr, path[i].Walkable ? greenTex : redTex); } } path = null; } }
void Display(string filename, IntPtr ptr) { AiScene scene = Assimp.MemoryHelper.Read <AiScene>(ptr); Debug.Log(scene.NumMeshes + " meshes"); Debug.Log(scene.NumMaterials + " materials"); Debug.Log(scene.NumTextures + " internal textures"); var texloader = new TextureLoader { scene = scene, basefilename = filename }; materials = new Material[scene.NumMaterials]; int materials_i = 0; foreach (var mat in Assimp.MemoryHelper.FromNativeArray <Assimp.Material, AiMaterial>(scene.Materials, (int)scene.NumMaterials, true)) { var mat1 = new Material(material); mat1.color = ToColor(mat.ColorDiffuse); if (mat.HasTextureDiffuse) { var tex = texloader.Load(mat); if (tex != null) { mat1.mainTexture = tex; } } materials[materials_i++] = mat1; } mesh2mat = new Material[scene.NumMeshes]; meshes = new Mesh[scene.NumMeshes]; int meshes_i = 0; foreach (var mesh in ReadArrayOfPtr <AiMesh>(scene.Meshes, scene.NumMeshes)) { //Debug.Log(" - " + mesh.Name); var mesh1 = new Mesh(); mesh1.name = mesh.Name.GetString(); var vertices = ReadArrayVector3(mesh.Vertices, mesh.NumVertices); mesh1.vertices = vertices; if (mesh.TextureCoords.Length > 0) { IntPtr texCoordsPtr = mesh.TextureCoords[0]; if (texCoordsPtr != IntPtr.Zero) { mesh1.uv = ReadArrayVector3_to_Vector2(texCoordsPtr, mesh.NumVertices); } } List <int> tris = new List <int>(); AiFace[] faces = ReadArrayInline <AiFace>(mesh.Faces, mesh.NumFaces); foreach (var face in faces) { var triangle = ReadArrayInt(face.Indices, face.NumIndices); if (triangle.Length == 3) { /* XXX for Unity to display meshes properly if they are used in a node with * a negative-determinant transformation, we'd need to swap the orientation * here. */ tris.Add(triangle[0]); tris.Add(triangle[2]); tris.Add(triangle[1]); } else { string s = string.Join(", ", triangle.Select(i => vertices[i])); Debug.Log("polygon with " + triangle.Length + " vertices: " + s); } } mesh1.SetTriangles(tris, 0); mesh1.RecalculateBounds(); mesh1.RecalculateNormals(); mesh2mat[meshes_i] = materials[mesh.MaterialIndex]; meshes[meshes_i++] = mesh1; } AiNode root = Assimp.MemoryHelper.Read <AiNode>(scene.RootNode); Recurse(transform, root); }
/// <summary> /// Returns the shortest path from source to destination /// using A* algorithm. /// </summary> /// <param name='src' type='GameObject'> /// Source. /// </param> /// <param name='dst' type='GameObject'> /// Destination /// </param> public List<GameObject> Astar(GameObject src, GameObject dst) { List<AiEdge> successors; AiVertex auxVertex; int cost = 0; bool isInFrontier = false, isInExplored = false; AiNode node = new AiNode(src, 1); AiNode dstNode = new AiNode(dst, 1); AiNode child; GPWiki.BinaryHeap<AiNode> frontier = new GPWiki.BinaryHeap<AiNode>(); List<GameObject> explored = new List<GameObject>(); frontier.Add(node); while (true) { if (frontier.Count == 0) return new List<GameObject>(); node = frontier.Remove(); explored.Add(node.m_GameObject); if (node.Equals(dstNode)) return explored; auxVertex = node.m_GameObject.GetComponent<AiVertex>(); successors = auxVertex.m_Successors; foreach (AiEdge e in successors) { cost = e.m_Cost; cost += (int)Vector3.Distance(e.m_Vertex.gameObject.transform.position, dst.transform.position); child = new AiNode(e.m_Vertex.gameObject, cost); isInFrontier = frontier.Contains(child); isInExplored = explored.Contains(child.m_GameObject); if (!isInExplored && !isInFrontier) frontier.Add(child); else if (isInFrontier) { foreach (AiNode n in frontier) { if (n.Equals(child) && (n.m_Cost > child.m_Cost)) { frontier.Remove(child); frontier.Add(child); } } } } } }