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();
        }
Пример #2
0
        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);
        }