private void Item_Click(object sender, RoutedEventArgs e) { labelMessage.IsEnabled = false; if (null != m_Timer) { m_Timer.Stop(); m_Timer = null; } if (null != m_Scene) { m_Scene.Dispose(); m_Scene = null; } string strDeviceName = (sender as MenuItem).Header.ToString(); m_Scene = new OpenCLRenderer.Scene(); string strVertexShader = File.ReadAllText("VertexShader.txt"); string strRayShader = File.ReadAllText("RayShader.txt"); m_Scene.CreateDevice(strDeviceName, @strVertexShader, @strRayShader); //Mutex mtxMutex = new Mutex(); Random rand = new Random(); { // load from obj file string strDirectory = @".\"; OBJLoader objLoader = new OBJLoader(); //mtxMutex.WaitOne(); objLoader.LoadFromFile(@strDirectory, @"Scene.obj"); //mtxMutex.ReleaseMutex(); // convert to triangle list int iMatrixId = m_Scene.GenMatrix(); m_Scene.SetMatrix(iMatrixId, Matrix4.Identity); List <OpenCLRenderer.Triangle> triangles = new List <OpenCLRenderer.Triangle>(); foreach (OBJLoader.Material material in objLoader.materials) { string strDiffuseTextureName = @strDirectory + @material.texture_filename; string strSpecularTextureName = @strDirectory + @"Specular.bmp"; string strNormalTextureName = @strDirectory + @"Normal.bmp"; int iMaterialId = m_Scene.GenMaterial(); m_Scene.SetMaterial(iMaterialId, @strDiffuseTextureName, @strSpecularTextureName, @strNormalTextureName); for (int i = 0; i < material.indices.Count; i += 3) { Vector3 vA = objLoader.vertices[material.indices[i + 0].id_vertex]; Vector3 vB = objLoader.vertices[material.indices[i + 1].id_vertex]; Vector3 vC = objLoader.vertices[material.indices[i + 2].id_vertex]; Vector3 nA = objLoader.normals[material.indices[i + 0].id_normal]; Vector3 nB = objLoader.normals[material.indices[i + 1].id_normal]; Vector3 nC = objLoader.normals[material.indices[i + 2].id_normal]; Vector2 tA = objLoader.text_coords[material.indices[i + 0].id_textcoord]; Vector2 tB = objLoader.text_coords[material.indices[i + 1].id_textcoord]; Vector2 tC = objLoader.text_coords[material.indices[i + 2].id_textcoord]; OpenCLRenderer.Vertex vertexA = new OpenCLRenderer.Vertex(); vertexA.m_Vx = vA.X; vertexA.m_Vy = vA.Y; vertexA.m_Vz = vA.Z; vertexA.m_Nx = nA.X; vertexA.m_Ny = nA.Y; vertexA.m_Nz = nA.Z; vertexA.m_TCx = tA.X; vertexA.m_TCy = tA.Y; vertexA.m_iNumMatrices = 1; vertexA.m_iMatrixId1 = iMatrixId; vertexA.m_fWeight1 = 1.0f; vertexA.m_iMatrixId2 = -1; vertexA.m_fWeight2 = 0.0f; vertexA.m_iMatrixId3 = -1; vertexA.m_fWeight3 = 0.0f; OpenCLRenderer.Vertex vertexB = new OpenCLRenderer.Vertex(); vertexB.m_Vx = vB.X; vertexB.m_Vy = vB.Y; vertexB.m_Vz = vB.Z; vertexB.m_Nx = nB.X; vertexB.m_Ny = nB.Y; vertexB.m_Nz = nB.Z; vertexB.m_TCx = tB.X; vertexB.m_TCy = tB.Y; vertexB.m_iNumMatrices = 1; vertexB.m_iMatrixId1 = iMatrixId; vertexB.m_fWeight1 = 1.0f; vertexB.m_iMatrixId2 = -1; vertexB.m_fWeight2 = 0.0f; vertexB.m_iMatrixId3 = -1; vertexB.m_fWeight3 = 0.0f; OpenCLRenderer.Vertex vertexC = new OpenCLRenderer.Vertex(); vertexC.m_Vx = vC.X; vertexC.m_Vy = vC.Y; vertexC.m_Vz = vC.Z; vertexC.m_Nx = nC.X; vertexC.m_Ny = nC.Y; vertexC.m_Nz = nC.Z; vertexC.m_TCx = tC.X; vertexC.m_TCy = tC.Y; vertexC.m_iNumMatrices = 1; vertexC.m_iMatrixId1 = iMatrixId; vertexC.m_fWeight1 = 1.0f; vertexC.m_iMatrixId2 = -1; vertexC.m_fWeight2 = 0.0f; vertexC.m_iMatrixId3 = -1; vertexC.m_fWeight3 = 0.0f; OpenCLRenderer.Triangle newTriangle = new OpenCLRenderer.Triangle(); newTriangle.m_A = vertexA; newTriangle.m_B = vertexB; newTriangle.m_C = vertexC; newTriangle.m_iMaterialId = iMaterialId; triangles.Add(newTriangle); } } int iId; iId = m_Scene.GenObject(); OpenCLRenderer.BVHObject staticObject = m_Scene.CreateStaticObject(triangles, Matrix4.CreateScale(7.0f, 7.0f, 7.0f)); m_Scene.SetObject(iId, staticObject); objLoader.Release(); triangles.Clear(); // load from obj file strDirectory = @".\"; smd = new SMDLoader(); mesh = new Mesh(); //mtxMutex.WaitOne(); // HL1 smd.LoadReference(@strDirectory, @"Goblin_Reference.smd", mesh); smd.AddAnimation(@strDirectory, @"Goblin_Anim.smd", "Anim1", 30.0f); // HL2 //smd.LoadReference(@strDirectory, @"Antlion_guard_reference.smd", mesh); //smd.AddAnimation(@strDirectory, @"Antlion_idle.smd", "Anim1", 30.0f); smd.SetAnimation("Anim1"); iMatrixOffset = m_Scene.NumMatrices(); for (int i = 0; i < mesh.transforms.Count; i++) { iMatrixId = m_Scene.GenMatrix(); m_Scene.SetMatrix(iMatrixId, smd.GetMatrix(i) * Matrix4.CreateScale(0.75f) * Matrix4.CreateRotationX(-1.57f) * Matrix4.CreateRotationY(0) * Matrix4.CreateTranslation(10, 0, -50)); } //int iMatrixId = m_Scene.GenMatrix(); //m_Scene.SetMatrix(iMatrixId, Matrix4.CreateRotationX(-1.57f) * Matrix4.CreateRotationY(3.14f)); //mtxMutex.ReleaseMutex(); triangles = new List <OpenCLRenderer.Triangle>(); foreach (Mesh.Material material in mesh.materials) { string strDiffuseTextureName = @strDirectory + @material.texture_name; string strSpecularTextureName = @strDirectory + @"Specular.bmp"; string strNormalTextureName = @strDirectory + @"Normal.bmp"; int iMaterialId = m_Scene.GenMaterial(); m_Scene.SetMaterial(iMaterialId, @strDiffuseTextureName, @strSpecularTextureName, @strNormalTextureName); for (int i = 0; i < material.vertices.Count(); i += 3) { // add triangle Mesh.Vertex meshVertexA = material.vertices[i + 0]; Mesh.Vertex meshVertexB = material.vertices[i + 1]; Mesh.Vertex meshVertexC = material.vertices[i + 2]; Vector3 vA = meshVertexA.vertex; Vector3 vB = meshVertexB.vertex; Vector3 vC = meshVertexC.vertex; // none normal vector Vector3 nA = meshVertexA.normal; Vector3 nB = meshVertexB.normal; Vector3 nC = meshVertexC.normal; Vector2 tA = meshVertexA.textcoords; Vector2 tB = meshVertexB.textcoords; Vector2 tC = meshVertexC.textcoords; OpenCLRenderer.Vertex vertexA = new OpenCLRenderer.Vertex(); vertexA.m_Vx = vA.X; vertexA.m_Vy = vA.Y; vertexA.m_Vz = vA.Z; vertexA.m_Nx = nA.X; vertexA.m_Ny = nA.Y; vertexA.m_Nz = nA.Z; vertexA.m_TCx = tA.X; vertexA.m_TCy = tA.Y; vertexA.m_iNumMatrices = meshVertexA.matrices.Count; for (int j = 0; j < vertexA.m_iNumMatrices; j++) { if (j == 0) { vertexA.m_iMatrixId1 = iMatrixOffset + meshVertexA.matrices[j].matrix_id; vertexA.m_fWeight1 = meshVertexA.matrices[j].weight; } if (j == 1) { vertexA.m_iMatrixId2 = iMatrixOffset + meshVertexA.matrices[j].matrix_id; vertexA.m_fWeight2 = meshVertexA.matrices[j].weight; } if (j == 2) { vertexA.m_iMatrixId3 = iMatrixOffset + meshVertexA.matrices[j].matrix_id; vertexA.m_fWeight3 = meshVertexA.matrices[j].weight; } } OpenCLRenderer.Vertex vertexB = new OpenCLRenderer.Vertex(); vertexB.m_Vx = vB.X; vertexB.m_Vy = vB.Y; vertexB.m_Vz = vB.Z; vertexB.m_Nx = nB.X; vertexB.m_Ny = nB.Y; vertexB.m_Nz = nB.Z; vertexB.m_TCx = tB.X; vertexB.m_TCy = tB.Y; vertexB.m_iNumMatrices = meshVertexB.matrices.Count; for (int j = 0; j < vertexB.m_iNumMatrices; j++) { if (j == 0) { vertexB.m_iMatrixId1 = iMatrixOffset + meshVertexB.matrices[j].matrix_id; vertexB.m_fWeight1 = meshVertexB.matrices[j].weight; } if (j == 1) { vertexB.m_iMatrixId2 = iMatrixOffset + meshVertexB.matrices[j].matrix_id; vertexB.m_fWeight2 = meshVertexB.matrices[j].weight; } if (j == 2) { vertexB.m_iMatrixId3 = iMatrixOffset + meshVertexB.matrices[j].matrix_id; vertexB.m_fWeight3 = meshVertexB.matrices[j].weight; } } OpenCLRenderer.Vertex vertexC = new OpenCLRenderer.Vertex(); vertexC.m_Vx = vC.X; vertexC.m_Vy = vC.Y; vertexC.m_Vz = vC.Z; vertexC.m_Nx = nC.X; vertexC.m_Ny = nC.Y; vertexC.m_Nz = nC.Z; vertexC.m_TCx = tC.X; vertexC.m_TCy = tC.Y; vertexC.m_iNumMatrices = meshVertexC.matrices.Count; for (int j = 0; j < vertexC.m_iNumMatrices; j++) { if (j == 0) { vertexC.m_iMatrixId1 = iMatrixOffset + meshVertexC.matrices[j].matrix_id; vertexC.m_fWeight1 = meshVertexC.matrices[j].weight; } if (j == 1) { vertexC.m_iMatrixId2 = iMatrixOffset + meshVertexC.matrices[j].matrix_id; vertexC.m_fWeight2 = meshVertexC.matrices[j].weight; } if (j == 2) { vertexC.m_iMatrixId3 = iMatrixOffset + meshVertexC.matrices[j].matrix_id; vertexC.m_fWeight3 = meshVertexC.matrices[j].weight; } } OpenCLRenderer.Triangle newTriangle = new OpenCLRenderer.Triangle(); newTriangle.m_A = vertexA; newTriangle.m_B = vertexB; newTriangle.m_C = vertexC; newTriangle.m_iMaterialId = iMaterialId; triangles.Add(newTriangle); } } //int iId; iId = m_Scene.GenObject(); OpenCLRenderer.BVHObject dynamicObject = m_Scene.CreateDynamicObject(triangles); m_Scene.SetObject(iId, dynamicObject); triangles.Clear(); } m_Scene.Commit(); Image_SizeChanged(null, null); m_Timer = new DispatcherTimer(); m_Timer.Tick += Timer_Tick; m_Timer.Interval = TimeSpan.FromMilliseconds(0); m_ElapsedTime = m_CurrentTime = DateTime.Now; m_fSec = 0.0f; m_fFullTime = 0.0f; m_Timer.Start(); }
public bool LoadReference(string directory, string filename, Mesh mesh) { string[] lines = File.ReadAllText(directory + @"/" + filename).Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); int mat_id = -1; bool is_nodes = false; bool is_skeleton_header = false; bool is_skeleton = false; bool is_triangles_texturename = false; bool is_triangles_v = false; int is_triangles_vrepeat = 0; foreach (string line in lines) { string[] words = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (words[0] == "nodes") { is_nodes = true; continue; } if (words[0] == "skeleton") { is_skeleton_header = true; continue; } if (words[0] == "triangles") { is_triangles_texturename = true; continue; } if (is_nodes) { if (words[0] == "end") { is_nodes = false; continue; } string node_name = ""; int i = 1; bool words_ok = false; while (!words_ok) { node_name += ((i == 1) ? "" : " ") + words[i]; if (words[i][words[i].Length - 1] == '"') { words_ok = true; } i++; } nodes.Add(new Node(node_name, int.Parse(words[i]))); } if (is_skeleton_header) { is_skeleton_header = false; is_skeleton = true; continue; } if (is_skeleton) { if (words[0] == "end") { is_skeleton = false; continue; } reference_skeleton.bones.Add(new Bone(new Vector3(ToFloat(words[1]), ToFloat(words[2]), ToFloat(words[3])), new Vector3(ToFloat(words[4]), ToFloat(words[5]), ToFloat(words[6])))); } if (is_triangles_texturename) { if (words[0] == "end") { is_triangles_texturename = false; continue; } string texture_name = line;// String.Join(" ", words); if (!material_to_id.ContainsKey(texture_name)) { mat_id = material_to_id.Count; material_to_id.Add(texture_name, mat_id); mesh.materials.Add(new Mesh.Material(texture_name)); } else { mat_id = material_to_id[texture_name]; } is_triangles_texturename = false; is_triangles_v = true; is_triangles_vrepeat = 0; continue; } if (is_triangles_v) { if (words.Count() == 9) // HL1 { mesh.is_obj = false; mesh.is_hl1 = true; mesh.is_hl2 = false; // matrix int matrix_id = int.Parse(words[0]); float weight = 1.0f; // vertex Vector3 v = new Vector3(ToFloat(words[1]), ToFloat(words[2]), ToFloat(words[3])); // normal Vector3 n = new Vector3(ToFloat(words[4]), ToFloat(words[5]), ToFloat(words[6])); // textcoords Vector2 t = new Vector2(ToFloat(words[7]), ToFloat(words[8])); Mesh.Vertex vertex = new Mesh.Vertex(v, n, t); // one matrix vertex.AddMatrix(matrix_id, weight); // add mesh.materials[mat_id].vertices.Add(vertex); } else // HL2 { mesh.is_obj = false; mesh.is_hl1 = false; mesh.is_hl2 = true; // vertex Vector3 v = new Vector3(ToFloat(words[1]), ToFloat(words[2]), ToFloat(words[3])); // normal Vector3 n = new Vector3(ToFloat(words[4]), ToFloat(words[5]), ToFloat(words[6])); // textcoords Vector2 t = new Vector2(ToFloat(words[7]), ToFloat(words[8])); Mesh.Vertex vertex = new Mesh.Vertex(v, n, t); // many matrix int num = int.Parse(words[9]); int id = 10; for (int i = 0; i < num; i++) { // matrix int matrix_id = int.Parse(words[id++]); float weight = ToFloat(words[id++]); // add vertex.AddMatrix(matrix_id, weight); } // add mesh.materials[mat_id].vertices.Add(vertex); } is_triangles_vrepeat++; if (is_triangles_vrepeat == 3) { is_triangles_v = false; is_triangles_texturename = true; continue; } continue; } } // min-max mesh.min = new Vector3(+1000000.0f, +1000000.0f, +1000000.0f); mesh.max = new Vector3(-1000000.0f, -1000000.0f, -1000000.0f); foreach (Mesh.Material material in mesh.materials) { foreach (Mesh.Vertex vertex in material.vertices) { Vector3 v = vertex.vertex; // min if (v.X < mesh.min.X) { mesh.min.X = v.X; } if (v.Y < mesh.min.Y) { mesh.min.Y = v.Y; } if (v.Z < mesh.min.Z) { mesh.min.Z = v.Z; } // max if (mesh.max.X < v.X) { mesh.max.X = v.X; } if (mesh.max.Y < v.Y) { mesh.max.Y = v.Y; } if (mesh.max.Z < v.Z) { mesh.max.Z = v.Z; } } } // init current skeleton for (int i = 0; i < reference_skeleton.bones.Count(); i++) { current_skeleton.bones.Add(new Bone(new Vector3(0, 0, 0), new Vector3(0, 0, 0))); } // calc matrices mesh.transforms = new List <Matrix4>(); for (int i = 0; i < reference_skeleton.bones.Count(); i++) { mesh.transforms.Add(new Matrix4()); } mesh.inverse_transforms_reference = new List <Matrix4>(); for (int i = 0; i < reference_skeleton.bones.Count(); i++) { mesh.inverse_transforms_reference.Add(new Matrix4()); } for (int i = 0; i < reference_skeleton.bones.Count(); i++) { Matrix4 invert = GetReferenceMatrix(i); mesh.inverse_transforms_reference[i] = invert; } for (int i = 0; i < mesh.materials.Count; i++) { Mesh.Material material = mesh.materials[i]; for (int j = 0; j < material.vertices.Count; j++) { Mesh.Vertex vertex = material.vertices[j]; Matrix4 inverseTransform = mesh.inverse_transforms_reference[vertex.matrices[0].matrix_id] * vertex.matrices[0].weight; for (int k = 1; k < vertex.matrices.Count; k++) { inverseTransform += mesh.inverse_transforms_reference[vertex.matrices[i].matrix_id] * vertex.matrices[i].weight; } inverseTransform.Invert(); // vertex vertex.vertex = new Vector3(new Vector4(vertex.vertex, 1.0f) * inverseTransform); // normal vertex.normal = new Vector3(new Vector4(vertex.normal, 0.0f) * inverseTransform); } } return(true); }