/// <summary>
        /// Builds a dictionary of parts to be emphasized if displaying wireframe.
        /// </summary>
        /// <remarks>
        /// During rendering, as the mesh tree is traversed each part is checked to
        /// see whether it should be displayed as wireframe or not. A part in the dictionary
        /// built by this method will be rendered as a solid part, otherwise the part
        /// will be rendered as wireframe.
        /// This method traverses the mesh tree looking for the named part. Once that
        /// named part is found, that part and all its children are added to the dictionary.
        /// The traversal is terminated once the named part has been found and all of its
        /// children have also been traversed (and added to the dictionary).
        /// </remarks>
        /// <param name="part">The current part to inspect</param>
        /// <param name="partName">The name of the root part to emphasize during rendering</param>
        /// <param name="fEmphasizeParent">True if the parent of this part will be emphasized, false otherwise</param>
        /// <returns>True if this part has been emphasized, false otherwise</returns>
        private bool BuildEmphasisDictionary(Part part, string partName, bool fEmphasizeParent)
        {
            if (fEmphasizeParent || (!string.IsNullOrEmpty(part.name) && part.name == partName))
            {
                partEmphasis.Add(part);
                fEmphasizeParent = true;
            }

            foreach (Part childPart in part.parts)
            {
                if (BuildEmphasisDictionary(childPart, partName, fEmphasizeParent) && !fEmphasizeParent)
                {
                    break;
                }
            }

            return fEmphasizeParent;
        }
        private void GetParts(Part part, List<string> names)
        {
            if (!string.IsNullOrEmpty(part.name))
            {
                names.Add(part.name);
            }

            foreach (Part childPart in part.parts)
            {
                GetParts(childPart, names);
            }
        }
        internal override ShaderResourceView UpdateRasterizerStateForPart(Part part)
        {
            RasterizerState state = 
                showOneTexture && !partEmphasis.Contains(part) ? wireframeRasterizerState : solidRasterizerState;

            if (state != currentRasterizerState)
            {
                this.manager.device.RS.State = currentRasterizerState = state;
            }

            ShaderResourceView textureOverride;

            if (!alternateTextures.TryGetValue(part.name, out textureOverride))
            {
                textureOverride = null;
            }

            return textureOverride;
        }
Example #4
0
 internal virtual ShaderResourceView UpdateRasterizerStateForPart(Part part)
 {
     return null;
 }
Example #5
0
        /// <summary>
        /// Loads a mesh and creates the vertex/index buffers for the part
        /// </summary>
        /// <param name="part"></param>
        /// <param name="meshData"></param>
        void LoadMesh(ref Part part, IXDataObject dataObject)
        {
            // load vertex data
            int dataOffset = 0;
            Match vertexCount = findArrayCount.Match(dataObject.Body);
            if(!vertexCount.Success)
                throw new System.IO.InvalidDataException("problem reading vertex count");

            List<Vector4F> vertexList = new List<Vector4F>();
            int verticies = int.Parse(vertexCount.Groups[1].Value, CultureInfo.InvariantCulture);
            dataOffset = vertexCount.Index + vertexCount.Length;
            for(int vertexIndex = 0; vertexIndex < verticies; vertexIndex++)
            {
                Match vertex = findVector3F.Match(dataObject.Body, dataOffset);
                if(!vertex.Success)
                    throw new System.IO.InvalidDataException("problem reading vertex");
                else
                    dataOffset = vertex.Index + vertex.Length;

                vertexList.Add(
                    new Vector4F(
                        float.Parse(vertex.Groups[1].Value, CultureInfo.InvariantCulture),
                        float.Parse(vertex.Groups[2].Value, CultureInfo.InvariantCulture),
                        float.Parse(vertex.Groups[3].Value, CultureInfo.InvariantCulture),
                        1.0f));
            }

            // load triangle index data
            Match triangleIndexCount = findArrayCount.Match(dataObject.Body, dataOffset);
            dataOffset = triangleIndexCount.Index + triangleIndexCount.Length;
            if(!triangleIndexCount.Success)
                throw new System.IO.InvalidDataException("problem reading index count");

            List<Int32> triangleIndiciesList = new List<Int32>();
            int triangleIndexListCount = int.Parse(triangleIndexCount.Groups[1].Value, CultureInfo.InvariantCulture);
            dataOffset = triangleIndexCount.Index + triangleIndexCount.Length;
            for(int triangleIndicyIndex = 0; triangleIndicyIndex < triangleIndexListCount; triangleIndicyIndex++)
            {
                Match indexEntry = findVertexIndex.Match(dataObject.Body, dataOffset);
                if(!indexEntry.Success)
                    throw new System.IO.InvalidDataException("problem reading vertex index entry");
                else
                    dataOffset = indexEntry.Index + indexEntry.Length;

                int indexEntryCount = int.Parse(indexEntry.Groups[1].Value, CultureInfo.InvariantCulture);
                string[] vertexIndexes = indexEntry.Groups[2].Value.Split(new char[] { ',' });
                if(indexEntryCount != vertexIndexes.Length)
                    throw new System.IO.InvalidDataException("vertex index count does not equal count of indicies found");

                for(int entryIndex = 0; entryIndex <= indexEntryCount - 3; entryIndex++)
                {
                    triangleIndiciesList.Add(int.Parse(vertexIndexes[0], CultureInfo.InvariantCulture));
                    triangleIndiciesList.Add(int.Parse(vertexIndexes[1 + entryIndex].ToString(), CultureInfo.InvariantCulture));
                    triangleIndiciesList.Add(int.Parse(vertexIndexes[2 + entryIndex].ToString(), CultureInfo.InvariantCulture));
                }
            }

            // load mesh colors
            IXDataObject vertexColorData = GetSingleChild(dataObject, "MeshVertexColors");
            Dictionary<int, Vector4F> colorDictionary = null;
            if (vertexColorData != null)
                colorDictionary = LoadMeshColors(vertexColorData);

            // load mesh normals
            IXDataObject meshNormalData = GetSingleChild(dataObject, "MeshNormals");
            IndexedMeshNormals meshNormals = null;
            if(meshNormalData != null)
            {
                meshNormals = LoadMeshNormals(meshNormalData);
            }

            // load mesh texture coordinates
            IXDataObject meshTextureCoordsData = GetSingleChild(dataObject, "MeshTextureCoords");
            List<Vector2F> meshTextureCoords = null;
            if(meshTextureCoordsData != null)
            {
                meshTextureCoords = LoadMeshTextureCoordinates(meshTextureCoordsData);
            }

            // load mesh material
            IXDataObject meshMaterialsData = GetSingleChild(dataObject, "MeshMaterialList");
            List<MaterialSpecification> meshMaterials = null;
            if(meshMaterialsData != null)
            {
                meshMaterials = LoadMeshMaterialList(meshMaterialsData);
            }
            
            // copy vertex data to HGLOBAL
            int byteLength = Marshal.SizeOf(typeof(XMeshVertex)) * triangleIndiciesList.Count;
            IntPtr nativeVertex = Marshal.AllocHGlobal(byteLength);
            byte[] byteBuffer = new byte[byteLength];
            XMeshVertex[] varray = new XMeshVertex[triangleIndiciesList.Count];
            for(int n = 0; n < triangleIndiciesList.Count; n++)
            {
                XMeshVertex vertex = new XMeshVertex()
                {
                    Vertex = vertexList[triangleIndiciesList[n]],
                    Normal = (meshNormals == null) ? new Vector4F(0, 0, 0, 1.0f) : meshNormals.normalVectors[meshNormals.normalIndexMap[n]],
                    Color = ((colorDictionary == null) ? new Vector4F(0, 0, 0, 0) : colorDictionary[triangleIndiciesList[n]]),
                    Texture = ((meshTextureCoords == null) ? new Vector2F(0, 0) : meshTextureCoords[triangleIndiciesList[n]])
                };
                byte[] vertexData = RawSerialize(vertex);
                Buffer.BlockCopy(vertexData, 0, byteBuffer, vertexData.Length * n, vertexData.Length);
            }
            Marshal.Copy(byteBuffer, 0, nativeVertex, byteLength);

            // build vertex buffer
            BufferDescription bdv = new BufferDescription()
            {
                Usage = Usage.Default,
                ByteWidth = (uint)(Marshal.SizeOf(typeof(XMeshVertex)) * triangleIndiciesList.Count),
                BindingOptions = BindingOptions.VertexBuffer,
                CpuAccessOptions = CpuAccessOptions.None,
                MiscellaneousResourceOptions = MiscellaneousResourceOptions.None
            };
            SubresourceData vertexInit = new SubresourceData()
            {
                SystemMemory = nativeVertex
            };

            part.vertexBuffer = device.CreateBuffer(bdv, vertexInit);
            Debug.Assert(part.vertexBuffer != null);


            part.vertexCount = triangleIndiciesList.Count;

            if(meshMaterials != null)
            {
                // only a single material is currently supported
                MaterialSpecification m = meshMaterials[0];

                part.material = new Material()
                {
                    emissiveColor = m.emissiveColor,
                    specularColor = m.specularColor,
                    materialColor = m.materialColor,
                    specularPower = m.specularPower
                };
                
                string texturePath = "";
                if(File.Exists(m.textureFileName))
                    texturePath = m.textureFileName;
                if(File.Exists(meshDirectory + "\\" + m.textureFileName))
                    texturePath = meshDirectory + "\\" + m.textureFileName;
                if(File.Exists(meshDirectory + "\\..\\" + m.textureFileName))
                    texturePath = meshDirectory + "\\..\\" + m.textureFileName;

                if(texturePath.Length == 0)
                {
                    part.material.textureResource = null;
                }
                else
                {
                    part.material.textureResource =
                        D3D10XHelpers.CreateShaderResourceViewFromFile(
                            device,
                            texturePath);
                }
            }
            Marshal.FreeHGlobal(nativeVertex);
        }
Example #6
0
        private void DisposePart(Part part)
        {
            if (part.vertexBuffer != null)
            {
                part.vertexBuffer.Dispose();
                part.vertexBuffer = null;
            }
            if ((part.material != null) && (part.material.textureResource != null))
            {
                part.material.textureResource.Dispose();
                part.material.textureResource = null;
            }

            foreach (Part childPart in part.parts)
            {
                DisposePart(childPart);
            }

            part.parts = null;
        }
Example #7
0
        private void RenderPart(Part part, Matrix3D parentMatrix, ShaderResourceView parentTextureOverride)
        {
            // set part transform
            Transform3DGroup partGroup = new Transform3DGroup();
            partGroup.Children.Add(new MatrixTransform3D(PartAnimation(part.name)));
            partGroup.Children.Add(new MatrixTransform3D(part.partTransform.ToMatrix3D()));
            partGroup.Children.Add(new MatrixTransform3D(parentMatrix));

            parentMatrix = partGroup.Value;

            ShaderResourceView textureOverride = UpdateRasterizerStateForPart(part);

            if (textureOverride == null)
            {
                textureOverride = parentTextureOverride;
            }
            else
            {
                parentTextureOverride = textureOverride;
            }

            if (part.vertexBuffer != null)
            {
                EffectTechnique technique;

                if (textureOverride != null)
                {
                    technique = this.manager.techniqueRenderTexture;
                    this.manager.diffuseVariable.Resource = textureOverride;
                }
                else if (part.material == null)
                {
                    technique = this.manager.techniqueRenderVertexColor;
                }
                else
                {
                    if (part.material.textureResource != null)
                    {
                        technique = this.manager.techniqueRenderTexture;
                        this.manager.diffuseVariable.Resource = part.material.textureResource;
                    }
                    else
                    {
                        technique = this.manager.techniqueRenderMaterialColor;
                        this.manager.materialColorVariable.FloatVector = part.material.materialColor;
                    }
                }

                this.manager.worldVariable.Matrix = parentMatrix.ToMatrix4x4F();

                //set up vertex buffer and index buffer
                uint stride = (uint)Marshal.SizeOf(typeof(XMeshVertex));
                uint offset = 0;
                this.manager.device.IA.SetVertexBuffers(0, new D3DBuffer[]
                    { part.vertexBuffer },
                    new uint[] { stride },
                    new uint[] { offset });

                //Set primitive topology
                this.manager.device.IA.PrimitiveTopology = PrimitiveTopology.TriangleList;

                TechniqueDescription techDesc = technique.Description;
                for (uint p = 0; p < techDesc.Passes; ++p)
                {
                    technique.GetPassByIndex(p).Apply();
                    PassDescription passDescription = technique.GetPassByIndex(p).Description;

                    using (InputLayout inputLayout = this.manager.device.CreateInputLayout(
                            part.dataDescription,
                            passDescription.InputAssemblerInputSignature,
                            passDescription.InputAssemblerInputSignatureSize))
                    {
                        // set vertex layout
                        this.manager.device.IA.InputLayout = inputLayout;

                        // draw part
                        this.manager.device.Draw((uint)part.vertexCount, 0);

                        // Note: In Direct3D 10, the device will not retain a reference
                        // to the input layout, so it's important to reset the device's
                        // input layout before disposing the object.  Were this code
                        // using Direct3D 11, the device would in fact retain a reference
                        // and so it would be safe to go ahead and dispose the input
                        // layout without resetting it; in that case, there could be just
                        // a single assignment to null outside the 'for' loop, or even
                        // no assignment at all.
                        this.manager.device.IA.InputLayout = null;
                    }
                }
            }

            foreach (Part childPart in part.parts)
            {
                RenderPart(childPart, parentMatrix, parentTextureOverride);
            }
        }
Example #8
0
        /// <summary>
        /// Loads a mesh and creates the vertex/index buffers for the part
        /// </summary>
        /// <param name="part"></param>
        /// <param name="meshData"></param>
        void LoadMesh( ref Part part, string meshData )
        {
            // load vertex data
            int dataOffset = 0;
            Match vertexCount = findArrayCount.Match( meshData );
            if( !vertexCount.Success )
                throw new System.IO.InvalidDataException( "problem reading vertex count" );

            List<Vector4F> vertexList = new List<Vector4F>();
            int verticies = int.Parse(vertexCount.Groups[1].Value, CultureInfo.InvariantCulture);
            dataOffset = vertexCount.Index + vertexCount.Length;
            for( int vertexIndex = 0; vertexIndex < verticies; vertexIndex++ )
            {
                Match vertex = findVector3F.Match( meshData, dataOffset );
                if( !vertex.Success )
                    throw new System.IO.InvalidDataException( "problem reading vertex" );
                else
                    dataOffset = vertex.Index + vertex.Length;

                vertexList.Add(
                    new Vector4F(
                        float.Parse(vertex.Groups[1].Value, CultureInfo.InvariantCulture),
                        float.Parse(vertex.Groups[2].Value, CultureInfo.InvariantCulture),
                        float.Parse(vertex.Groups[3].Value, CultureInfo.InvariantCulture),
                        1.0f) );
            }

            // load triangle index data
            Match triangleIndexCount = findArrayCount.Match( meshData, dataOffset );
            dataOffset = triangleIndexCount.Index + triangleIndexCount.Length;
            if( !triangleIndexCount.Success )
                throw new System.IO.InvalidDataException( "problem reading index count" );

            List<Int32> triangleIndiciesList = new List<Int32>( );
            int triangleIndexListCount = int.Parse(triangleIndexCount.Groups[1].Value, CultureInfo.InvariantCulture);
            dataOffset = triangleIndexCount.Index + triangleIndexCount.Length;
            for( int triangleIndicyIndex = 0; triangleIndicyIndex < triangleIndexListCount; triangleIndicyIndex++ )
            {
                Match indexEntry = findVertexIndex.Match( meshData, dataOffset );
                if( !indexEntry.Success )
                    throw new System.IO.InvalidDataException( "problem reading vertex index entry" );
                else
                    dataOffset = indexEntry.Index + indexEntry.Length;

                int indexEntryCount = int.Parse(indexEntry.Groups[1].Value, CultureInfo.InvariantCulture);
                string[ ] vertexIndexes = indexEntry.Groups[ 2 ].Value.Split( new char[ ] { ',' } );
                if( indexEntryCount != vertexIndexes.Length )
                    throw new System.IO.InvalidDataException( "vertex index count does not equal count of indicies found" );

                for( int entryIndex = 0; entryIndex <= indexEntryCount - 3; entryIndex++ )
                {
                    triangleIndiciesList.Add(int.Parse(vertexIndexes[0], CultureInfo.InvariantCulture));
                    triangleIndiciesList.Add(int.Parse(vertexIndexes[1 + entryIndex].ToString(), CultureInfo.InvariantCulture));
                    triangleIndiciesList.Add(int.Parse(vertexIndexes[2 + entryIndex].ToString(), CultureInfo.InvariantCulture));
                }
            }

            // load mesh colors
            string vertexColorData = GetTagContent( new Regex( @"MeshVertexColors[\s]+{" ), meshData );
            Dictionary<int,Vector4F> colorDictionary = null;
            if( vertexColorData != "" )
                colorDictionary = LoadMeshColors( vertexColorData );

            // load mesh normals
            string meshNormalData = GetTagContent( new Regex( @"MeshNormals[\s]+{" ), meshData );
            IndexedMeshNormals meshNormals = null;
            if( meshNormalData != "" )
            {
                meshNormals = LoadMeshNormals( meshNormalData );
            }

            // load mesh texture coordinates
            string meshTextureCoordsData = GetTagContent( new Regex( @"MeshTextureCoords[\s]+{" ), meshData );
            List<Vector2F> meshTextureCoords = null;
            if( meshTextureCoordsData != "" )
            {
                meshTextureCoords = LoadMeshTextureCoordinates( meshTextureCoordsData );
            }

            // load mesh material
            string meshMaterialsData = GetTagContent( new Regex( @"MeshMaterialList[\s]+{" ), meshData );
            List<MaterialSpecification> meshMaterials = null;
            if( meshMaterialsData != "" )
            {
                meshMaterials = LoadMeshMaterialList( meshMaterialsData );
            }
            
            // copy vertex data to HGLOBAL
            int byteLength = Marshal.SizeOf( typeof( XMeshVertex ) ) * triangleIndiciesList.Count;
            IntPtr nativeVertex = Marshal.AllocHGlobal( byteLength );
            byte[ ] byteBuffer = new byte[ byteLength ];
            XMeshVertex[ ] varray = new XMeshVertex[ triangleIndiciesList.Count ];
            for( int n = 0; n < triangleIndiciesList.Count; n++ )
            {
                XMeshVertex vertex = new XMeshVertex( )
                {
                    Vertex = vertexList[ triangleIndiciesList[ n ] ],
                    Normal = (meshNormals == null) ? new Vector4F( 0, 0, 0, 1.0f ) : meshNormals.normalVectors[ meshNormals.normalIndexMap[ n ] ],
                    Color = ((colorDictionary == null) ? new Vector4F( 0, 0, 0, 0 ) : colorDictionary[ triangleIndiciesList[ n ] ]),
                    Texture = ((meshTextureCoords == null) ? new Vector2F( 0, 0 ) : meshTextureCoords[ triangleIndiciesList[ n ] ])
                };
                byte[ ] vertexData = RawSerialize( vertex );
                Buffer.BlockCopy( vertexData, 0, byteBuffer, vertexData.Length * n, vertexData.Length );
            }
            Marshal.Copy( byteBuffer, 0, nativeVertex, byteLength );

            // build vertex buffer
            BufferDescription bdv = new BufferDescription( )
            {
                Usage = Usage.Default,
                ByteWidth = (uint)(Marshal.SizeOf( typeof( XMeshVertex ) ) * triangleIndiciesList.Count),
                BindFlags = BindFlag.VertexBuffer,
                CpuAccessFlags = 0,
                MiscFlags = 0
            };
            SubresourceData vertexInit = new SubresourceData( )
            {
                SysMem = nativeVertex
            };

            part.vertexBuffer = device.CreateBuffer( bdv, vertexInit );
            Debug.Assert( part.vertexBuffer != null );


            part.vertexCount = triangleIndiciesList.Count;

            if( meshMaterials != null )
            {
                // only a single material is currently supported
                MaterialSpecification m = meshMaterials[ 0 ];

                part.material = new Material()
                {
                    emissiveColor = m.emissiveColor,
                    specularColor = m.specularColor,
                    materialColor = m.materialColor,
                    specularPower = m.specularPower
                };
                
                string texturePath = "";
                if( File.Exists( m.textureFileName ) )
                    texturePath = m.textureFileName;
                if( File.Exists( meshDirectory + "\\" + m.textureFileName ) )
                    texturePath = meshDirectory + "\\" + m.textureFileName;
                if( File.Exists( meshDirectory + "\\..\\" + m.textureFileName ) )
                    texturePath = meshDirectory + "\\..\\" + m.textureFileName;

                if( texturePath.Length == 0 )
                {
                    part.material.textureResource = null;
                }
                else
                {
                    part.material.textureResource =
                        D3D10XHelpers.CreateShaderResourceViewFromFile(
                            device,
                            texturePath );
                }
            }
            Marshal.FreeHGlobal( nativeVertex );
        }
Example #9
0
        /// <summary>
        /// Extracts the vertex, normal, and texture data for a part
        /// </summary>
        /// <param name="partData"></param>
        /// <param name="partName"></param>
        /// <returns></returns>
        private Part BuildPart( string partData, string partName )
        {
            Part part = new Part( );

            part.dataDescription = description;
            part.name = partName;

            part.partTransform = ExtractFrameTransformation( partData );

            // extract mesh (vertex, index, and colors)
            string meshContents = GetTagContent( new Regex( @"Mesh[\s]?([\w\d_]+)?[\s]+{" ), partData );
            if( meshContents.Length > 0 )
                LoadMesh( ref part, meshContents );

            return part;
        }
        private Part PartFromDataObject(IXDataObject dataObject)
        {
            Part part = new Part();

            part.parts = new List<Part>();

            part.name = dataObject.Name;

            switch (dataObject.DataObjectType)
            {
                case "Frame":
                    // Frame data objects translate to parts with only a transform,
                    // and no vertices, materials, etc.
                    part.partTransform = ExtractFrameTransformation(dataObject);
                    foreach (IXDataObject childObject in dataObject.Children.Where(obj => obj.IsVisualObject))
                    {
                        part.parts.Add(PartFromDataObject(childObject));
                    }
                    break;
                case "Mesh":
                    // Mesh data objects inherit transform from their parent,
                    // but do have vertices, materials, etc.
                    part.partTransform = Matrix4x4F.Identity;
                    part.dataDescription = description;
                    LoadMesh(ref part, dataObject);
                    break;
                default:
                    throw new ArgumentException(
                        string.Format(CultureInfo.InvariantCulture,
                        "Object type \"{0}\" is incorrect. Only Frame or Mesh data objects can be converted to Part instances",
                        dataObject.DataObjectType));
            }

            return part;
        }