public static void ExtractModelMeshPartData(ModelMesh mm, ModelMeshPart mmp, ref Matrix xform,
            List<Vector3> vertices, List<TriangleVertexIndices> indices, string name)
        {
            int offset = vertices.Count;
            Vector3[] a = new Vector3[mmp.NumVertices];
            mm.VertexBuffer.GetData<Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride,
                a, 0, mmp.NumVertices, mmp.VertexStride);
            for (int i = 0; i != a.Length; ++i)
                Vector3.Transform(ref a[i], ref xform, out a[i]);
            vertices.AddRange(a);

            if (mm.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
                throw new Exception(
                    String.Format("Model {0} uses 32-bit indices, which are not supported.",
                                  name));
            short[] s = new short[mmp.PrimitiveCount * 3];
            mm.IndexBuffer.GetData<short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
            TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
            for (int i = 0; i != tvi.Length; ++i)
            {
                tvi[i].I0 = s[i * 3 + 0] + offset;
                tvi[i].I1 = s[i * 3 + 1] + offset;
                tvi[i].I2 = s[i * 3 + 2] + offset;
            }
            indices.AddRange(tvi);
        }
Esempio n. 2
0
        public PartMaterial(ModelMeshPart part)
        {
            MeshPart = part;
            DefaultEffect = part.Effect;
            DefaultParameters = EffectParameterListSave.FromEffect(part.Effect);

            SetDefaults();
        }
Esempio n. 3
0
        private void EnableEffect(ModelMeshPart meshPart)
        {
            var effect = (BasicEffect)meshPart.Effect;

            effect.World = LocalWorld;
            effect.View = View;
            effect.Projection = Projection;

            effect.EnableDefaultLighting();
        }
Esempio n. 4
0
		public static void DrawMeshPart( ModelMesh mesh, ModelMeshPart part, Effect effect ) {
			GraphicsDevice device = Puzzle3D.Instance.GraphicsDevice;

			foreach( EffectPass pass in effect.CurrentTechnique.Passes ) {
				pass.Begin();

				device.VertexDeclaration = part.VertexDeclaration;
				device.Vertices[ 0 ].SetSource( mesh.VertexBuffer, part.StreamOffset, part.VertexStride );
				device.Indices = mesh.IndexBuffer;

				device.DrawIndexedPrimitives( PrimitiveType.TriangleList, part.BaseVertex, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount );

				pass.End();
			}
		}
		public static Vector3[] GetVertexElement(ModelMeshPart meshPart, VertexElementUsage usage)
		{
			VertexDeclaration vd = meshPart.VertexBuffer.VertexDeclaration;
			VertexElement[] elements = vd.GetVertexElements();

			Func<VertexElement, bool> elementPredicate = ve => ve.VertexElementUsage == usage && ve.VertexElementFormat == VertexElementFormat.Vector3;
			if (!elements.Any(elementPredicate))
				return null;

			VertexElement element = elements.First(elementPredicate);

			Vector3[] vertexData = new Vector3[meshPart.NumVertices];
			meshPart.VertexBuffer.GetData((meshPart.VertexOffset * vd.VertexStride) + element.Offset,
				vertexData, 0, vertexData.Length, vd.VertexStride);

			return vertexData;
		}
Esempio n. 6
0
 internal ModelMesh(string name, ModelBone parentBone, BoundingSphere boundingSphere, VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart[] meshParts, object tag)
 {
     this.boundingSphere = new BoundingSphere();
     this.effects = new ModelEffectCollection();
     this.name = name;
     this.parentBone = parentBone;
     this.boundingSphere = boundingSphere;
     this.vertexBuffer = vertexBuffer;
     this.indexBuffer = indexBuffer;
     this.meshParts = new ModelMeshPartCollection(meshParts);
     this.tag = tag;
     int length = meshParts.Length;
     for (int i = 0; i < length; i++)
     {
         ModelMeshPart part = meshParts[i];
         part.parent = this;
     }
 }
Esempio n. 7
0
		private static NormalBuffers GetNormalBuffers(ModelMesh mesh, ModelMeshPart meshPart, GraphicsDevice graphicsDevice, float normalLengthPercentage)
		{
			if (meshPart.VertexBuffer == null)
				return null;

			Vector3[] positions = VertexElementExtractor.GetVertexElement(meshPart, VertexElementUsage.Position);
			if (positions == null)
				return null;
			Vector3[] normals = VertexElementExtractor.GetVertexElement(meshPart, VertexElementUsage.Normal);
			if (normals == null)
				return null;

			NormalBuffers normalBuffers = new NormalBuffers();

			normalBuffers.PrimitiveCount = normals.Length;
			normalBuffers.VertexCount = normals.Length * 2;

			float size = mesh.BoundingSphere.Radius * normalLengthPercentage;

			VertexBuffer vertexBuffer = new VertexBuffer(graphicsDevice,
				typeof (VertexPositionColor), normalBuffers.VertexCount,
				BufferUsage.WriteOnly);
			VertexPositionColor[] vertices = new VertexPositionColor[normalBuffers.VertexCount];
			int counter = 0;
			for (int i = 0; i < normals.Length; ++i)
			{
				Vector3 normalColorTemp = Vector3.Normalize(normals[i]);
				normalColorTemp += Vector3.One;
				normalColorTemp *= 0.5f;
				Color normalColor = new Color(normalColorTemp);
				vertices[counter++] = new VertexPositionColor(positions[i], normalColor);
				vertices[counter++] = new VertexPositionColor(positions[i] + (normals[i] * size), normalColor);
			}
			vertexBuffer.SetData(vertices);
			normalBuffers.Vertices = vertexBuffer;

			IndexBuffer indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, normalBuffers.VertexCount,
				BufferUsage.WriteOnly);
			indexBuffer.SetData(Enumerable.Range(0, normalBuffers.VertexCount).Select(i => (short) i).ToArray());
			normalBuffers.Indices = indexBuffer;

			return normalBuffers;
		}
Esempio n. 8
0
        private void CreateMeshPart(MODELMESHPART dstPart, MeshPrimitive srcPart, MeshNormalsFallback normalsFunc, int maxBones)
        {
            var doubleSided = srcPart.Material?.DoubleSided ?? false;

            var srcGeometry = new MeshPrimitiveReader(srcPart, doubleSided, normalsFunc);

            var eff = srcGeometry.IsSkinned ? _MatFactory.UseSkinnedEffect(srcPart.Material) : _MatFactory.UseRigidEffect(srcPart.Material);

            dstPart.Effect = eff;

            var vb = srcGeometry.IsSkinned ? CreateVertexBuffer(srcGeometry.ToXnaSkinned()) : CreateVertexBuffer(srcGeometry.ToXnaRigid());

            dstPart.VertexBuffer = vb;
            dstPart.NumVertices  = srcGeometry.VertexCount;
            dstPart.VertexOffset = 0;

            dstPart.IndexBuffer    = CreateIndexBuffer(srcGeometry.TriangleIndices);
            dstPart.PrimitiveCount = srcGeometry.TriangleIndices.Length;
            dstPart.StartIndex     = 0;
        }
Esempio n. 9
0
 public IndexArrayShort(ModelMeshPart part)
     : base(part)
 {
     Indices = new short[part.PrimitiveCount * 3];
     part.IndexBuffer.GetData<short>(part.StartIndex * sizeof(short), Indices, 0, part.PrimitiveCount * 3);
 }
Esempio n. 10
0
		private static void DrawMeshPart(ModelMeshPart meshPart)
		{
			if (meshPart.NumVertices > 0)
			{
				GraphicsDevice graphicsDevice = meshPart.VertexBuffer.GraphicsDevice;
				graphicsDevice.SetVertexBuffer(meshPart.VertexBuffer, meshPart.VertexOffset);
				graphicsDevice.Indices = meshPart.IndexBuffer;
				graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, meshPart.NumVertices,
					meshPart.StartIndex, meshPart.PrimitiveCount);
			}
		}
Esempio n. 11
0
 public IndexArray(ModelMeshPart part)
 {
 }
Esempio n. 12
0
        public virtual void PrepareShadows(ref Matrix renderMatrix)
        {
            if (!(shader is IShadowShader))
                return;

            foreach (ModelMesh modelMesh in this.mesh)
            {
                Matrix.Multiply(ref transforms[modelMesh.ParentBone.Index], ref renderMatrix, out tmpMat1);
                if (animationTransforms.Count > 0 && animationTransforms.ContainsKey(modelMesh.Name))
                    tmpMat1 = animationTransforms[modelMesh.Name] * tmpMat1;

                foreach (ModelMeshPart part in modelMesh.MeshParts)
                {
                    curPart = part;

                    ((IShadowShader)shader).ShadowMap.ComputeShadow(
                        ref tmpMat1,
                        SubmitGeometry);
                }
            }
        }
Esempio n. 13
0
		private static BoundingBox? GetBoundingBox(ModelMeshPart meshPart)
		{
			if (meshPart.VertexBuffer == null)
				return null;

			Vector3[] positions = VertexElementExtractor.GetVertexElement(meshPart, VertexElementUsage.Position);
			if (positions == null)
				return null;

			return BoundingBox.CreateFromPoints(positions);
		}
Esempio n. 14
0
        private static OutlineItem CreateOutlineItem(ModelMeshPart meshPart)
        {
            var item = new OutlineItem
            {
                Text = "ModelMeshPart",
                Icon = MultiColorGlyphs.Mesh,
                UserData = meshPart,
            };

            return item;
        }
Esempio n. 15
0
 public override Material CreateFromMeshPart(ModelMeshPart MeshPart)
 {
     base.CreateFromMeshPart(MeshPart);
     this.texture = GetTextureFromEffect(MeshPart.Effect);
     return this;
 }
Esempio n. 16
0
        private bool PartIsTranslucent(ModelMeshPart modelMeshPart)
        {
            bool result = false;

            if(modelMeshPart.Effect is BasicEffect){
                if((double)((BasicEffect)modelMeshPart.Effect).Alpha < 1.0)
                    result = true;
            }
            return result;
        }
        /// <summary>
        /// Do the actual replication of the indices, for each ModelMeshPart
        /// </summary>
        /// <param name="part"></param>
        /// <param name="indices"></param>
        /// <param name="oldIndices"></param>
        private void ReplicateIndexData(ModelMeshPart part, List<ushort> indices, ushort [] oldIndices)
        {
            // Replicate one copy of the original index buffer for each instance.
            for (int instanceIndex = 0; instanceIndex < maxInstances; instanceIndex++)
            {
                int instanceOffset = instanceIndex * vertexCount;

                // Basically, keep adding the indices. We have to replicate this ModelMeshPart index for each instance we can have
                // Note that each time we are incrementing by instanceOffset. This is so in the vertex shader, when we divide
                // by the vertex count, we know exactly which index we are at.
                for (int i = part.StartIndex; i < part.PrimitiveCount * 3; i++)
                {
                    indices.Add((ushort)(oldIndices[i] + instanceOffset));
                }
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Get all the triangles from each mesh part (Changed for XNA 4)
        /// </summary>
        public static void ExtractModelMeshPartData(ModelMeshPart meshPart, ref Matrix transform,
            List<Vector3> vertices, List<TriangleVertexIndices> indices)
        {
            // Before we add any more where are we starting from
            int offset = vertices.Count;

            // == Vertices (Changed for XNA 4.0)

            // Read the format of the vertex buffer
            VertexDeclaration declaration = meshPart.VertexBuffer.VertexDeclaration;
            VertexElement[] vertexElements = declaration.GetVertexElements();
            // Find the element that holds the position
            VertexElement vertexPosition = new VertexElement();
            foreach (VertexElement vert in vertexElements)
            {
                if (vert.VertexElementUsage == VertexElementUsage.Position &&
                    vert.VertexElementFormat == VertexElementFormat.Vector3)
                {
                    vertexPosition = vert;
                    // There should only be one
                    break;
                }
            }
            // Check the position element found is valid
            if (vertexPosition == null ||
                vertexPosition.VertexElementUsage != VertexElementUsage.Position ||
                vertexPosition.VertexElementFormat != VertexElementFormat.Vector3)
            {
                throw new Exception("Model uses unsupported vertex format!");
            }
            // This where we store the vertices until transformed
            Vector3[] allVertex = new Vector3[meshPart.NumVertices];
            // Read the vertices from the buffer in to the array
            meshPart.VertexBuffer.GetData<Vector3>(
                meshPart.VertexOffset * declaration.VertexStride + vertexPosition.Offset,
                allVertex,
                0,
                meshPart.NumVertices,
                declaration.VertexStride);
            // Transform them based on the relative bone location and the world if provided
            for (int i = 0; i != allVertex.Length; ++i)
            {
                Vector3.Transform(ref allVertex[i], ref transform, out allVertex[i]);
            }
            // Store the transformed vertices with those from all the other meshes in this model
            vertices.AddRange(allVertex);

            // == Indices (Changed for XNA 4)

            // Find out which vertices make up which triangles
            if (meshPart.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
            {
                // This could probably be handled by using int in place of short but is unnecessary
                throw new Exception("Model uses 32-bit indices, which are not supported.");
            }
            // Each primitive is a triangle
            short[] indexElements = new short[meshPart.PrimitiveCount * 3];
            // It looks like the same index buffer is referenced from each meshPart.
            meshPart.IndexBuffer.GetData<short>(
                meshPart.StartIndex * 2,
                indexElements,
                0,
                meshPart.PrimitiveCount * 3);
            // Each TriangleVertexIndices holds the three indexes to each vertex that makes up a triangle
            TriangleVertexIndices[] tvi = new TriangleVertexIndices[meshPart.PrimitiveCount];
            for (int i = 0; i != tvi.Length; ++i)
            {
                // The offset is because we are storing them all in the one array and the
                // vertices were added to the end of the array.
                tvi[i].A = indexElements[i * 3 + 0] + offset;
                tvi[i].B = indexElements[i * 3 + 1] + offset;
                tvi[i].C = indexElements[i * 3 + 2] + offset;
            }
            // Store our triangles
            indices.AddRange(tvi);
        }
Esempio n. 19
0
        private void DrawMeshPart(AccessMesh am, ModelMeshPart modelMeshPart,Matrix view, Matrix projection)
        {
            if(modelMeshPart.Effect is IEffectMatrices) {
                IEffectMatrices effectMatrices = modelMeshPart.Effect as IEffectMatrices;
                effectMatrices.Projection = projection;
                effectMatrices.View = view;
                effectMatrices.World = _meshTransform[am.MeshId]
                    * (_model.Meshes)[am.MeshId].ParentBone.Transform
                    * Matrix.CreateTranslation(_position);
            }

            _device.SetVertexBuffer(modelMeshPart.VertexBuffer);
            _device.Indices = modelMeshPart.IndexBuffer;
            foreach(EffectPass effectPass in modelMeshPart.Effect.CurrentTechnique.Passes) {
                effectPass.Apply();
                _device.DrawIndexedPrimitives(PrimitiveType.TriangleList, modelMeshPart.VertexOffset,
                    modelMeshPart.StartIndex, modelMeshPart.NumVertices, modelMeshPart.StartIndex, modelMeshPart.PrimitiveCount);
            }
        }
Esempio n. 20
0
 // Sets up material from values embedded in a MeshPart
 public virtual Material CreateFromMeshPart(ModelMeshPart MeshPart)
 {
     this.effect = MeshPart.Effect;
     return this;
 }
 /// <summary>
 /// Each model part will have several datastrutures associated with it so we need an array of objects to store them all
 /// </summary>
 /// <param name="part">Model mesh part under consideration</param>
 private static void ConstructCollisionDetectionInfoStore(ModelMeshPart part)
 {
     part.Tag = new object[2];
 }
Esempio n. 22
0
 public static bool m0001a8(ModelMeshPart p0)
 {
     foreach (VertexElement element in p0.VertexDeclaration.GetVertexElements())
     {
         if ((element.VertexElementUsage == VertexElementUsage.BlendIndices) && (element.UsageIndex == 0))
         {
             return true;
         }
     }
     return false;
 }
Esempio n. 23
0
 public VertexArray(ModelMeshPart part)
 {
     Vertices = new Vector3[part.NumVertices];
     part.VertexBuffer.GetData<Vector3>(part.VertexOffset * part.VertexBuffer.VertexDeclaration.VertexStride,
                         Vertices, 0, part.NumVertices, part.VertexBuffer.VertexDeclaration.VertexStride);
 }
Esempio n. 24
0
        private static BoundingBox? GetBoundingBox(ModelMeshPart meshPart, Matrix transform)
        {
            if (meshPart.VertexBuffer == null)
                return null;

            Vector3[] positions = GetVertexElement(meshPart, VertexElementUsage.Position);
            if (positions == null)
                return null;

            Vector3[] transformedPositions = new Vector3[positions.Length];
            Vector3.Transform(positions, ref transform, transformedPositions);

            return BoundingBox.CreateFromPoints(transformedPositions);
        }
Esempio n. 25
0
        /// <summary>
        /// Attaches this <see cref="ModelMesh"/> to a parent <see cref="model"/>.
        /// </summary>
        internal void Attach(Model model, Microsoft.Xna.Framework.Graphics.ModelMesh mesh, Microsoft.Xna.Framework.Graphics.ModelMeshPart part)
        {
            if (model == null || mesh == null || part == null)
            {
                throw new ArgumentNullException();
            }

            this.model = model;
            this.name  = mesh.Name;

            var tag = part.Tag as ModelMeshPartTag;

            if (tag != null && tag.Textures != null && tag.Textures.Count > 0)
            {
                this.textures = tag.Textures;
            }
            this.diffuseTexture  = part.Effect.GetTexture();
            this.parentBoneIndex = mesh.ParentBone.Index;
            this.vertexBuffer    = part.VertexBuffer;
            this.indexBuffer     = part.IndexBuffer;
            this.vertexOffset    = part.VertexOffset;
            this.numVertices     = part.NumVertices;
            this.primitiveCount  = part.PrimitiveCount;
            this.startIndex      = part.StartIndex;
        }
Esempio n. 26
0
 // Set the required values in the shader.
 private void SetupEffect(Matrix[] transforms, ModelMesh mesh, 
                         ModelMeshPart part)
 {
     Effect effect = part.Effect;
     effect.Parameters["TranslationAmount"].SetValue(translationRate * time);
     effect.Parameters["RotationAmount"].SetValue(rotationRate * time);
     effect.Parameters["time"].SetValue(time);            
     effect.Parameters["WorldViewProjection"].SetValue(
         transforms[mesh.ParentBone.Index] * view * projection);
     effect.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index]);
     effect.Parameters["eyePosition"].SetValue(cameraPosition);
     effect.Parameters["lightPosition"].SetValue(lightPosition);
     effect.Parameters["ambientColor"].SetValue(ambientColor);
     effect.Parameters["diffuseColor"].SetValue(diffuseColor);
     effect.Parameters["specularColor"].SetValue(specularColor);            
     effect.Parameters["specularPower"].SetValue(specularPower);            
 }
Esempio n. 27
0
        /// <summary>
        /// Renders the model itself as well as the minimum bounding box if showBoundingBox
        /// is true. By default, SimpleEffectShader is used to render the model.
        /// </summary>
        /// <remarks>
        /// This function is called automatically to render the model, so do not call this method
        /// </remarks>
        /// <param name="material">Material properties of this model</param>
        /// <param name="renderMatrix">Transform of this model</param>
        public virtual void Render(ref Matrix renderMatrix, Material material)
        {
            if (!UseInternalMaterials)
            {
                material.InternalEffect = null;
                if ((shader.CurrentMaterial != material) || material.HasChanged)
                {
                    shader.SetParameters(material);

                    foreach (IShader afterEffect in afterEffectShaders)
                        afterEffect.SetParameters(material);

                    material.HasChanged = false;
                }
            }

            BlendState origState = null;
            if (ContainsTransparency)
            {
                origState = State.Device.BlendState;
                State.AlphaBlendingEnabled = true;
            }

            // Render the actual model
            foreach (ModelMesh modelMesh in this.mesh)
            {
                Matrix.Multiply(ref transforms[modelMesh.ParentBone.Index], ref renderMatrix, out tmpMat1);
                if (animationTransforms.Count > 0 && animationTransforms.ContainsKey(modelMesh.Name))
                    tmpMat1 = animationTransforms[modelMesh.Name] * tmpMat1;

                foreach (ModelMeshPart part in modelMesh.MeshParts)
                {
                    if (UseInternalMaterials)
                    {
                        material.InternalEffect = part.Effect;
                        shader.SetParameters(material);
                    }

                    String techniqueName = technique;
                    if (String.IsNullOrEmpty(techniqueName))
                        techniqueName = part.Effect.CurrentTechnique.Name;
                    curPart = part;
                    shader.Render(
                        ref tmpMat1,
                        techniqueName,
                        SubmitGeometry);

                    foreach (IShader afterEffect in afterEffectShaders)
                    {
                        if (UseInternalMaterials)
                            afterEffect.SetParameters(material);

                        afterEffect.Render(
                            ref tmpMat1,
                            "",
                            ResubmitGeometry);
                    }
                }
            }

            shader.RenderEnd();
            foreach (IShader afterEffect in afterEffectShaders)
                afterEffect.RenderEnd();

            if (ContainsTransparency)
                State.Device.BlendState = origState;

            if (showBoundingBox)
                RenderBoundingBox(ref renderMatrix);
        }
 private static Int32[] LoadIndexBuffer(ModelMeshPart thisPart)
 {
     int numIndices = thisPart.IndexBuffer.IndexCount;
     Int32[] localIndexBuffer = new Int32[numIndices];
     if (thisPart.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits)
     {
                 Int16[] tmpI = new Int16[numIndices];
                 thisPart.IndexBuffer.GetData<Int16>(tmpI);
                 for (int i = 0; i < numIndices; i++)
                     localIndexBuffer[i] = (Int32)tmpI[i];
     }
     else
     {
                 thisPart.IndexBuffer.GetData<Int32>(localIndexBuffer);
     }
     return localIndexBuffer;
 }
        /// <summary>
        /// DrawPart draws the actual ModelMeshPart
        /// </summary>
        /// <param name="transforms"></param>
        /// <param name="animations"></param>
        /// <param name="effect"></param>
        /// <param name="part"></param>
        private void DrawPart(Matrix [] transforms, int [] animations, Effect effect, ModelMeshPart part)
        {
            for (int i = 0; i < transforms.Length; i += maxInstances)
            {
                // How many instances can we fit into this batch?
                int instanceCount = transforms.Length- i;

                if (instanceCount > maxInstances)
                    instanceCount = maxInstances;

                // Copy transform and animation data
                Array.Copy(transforms, i, tempTransforms, 0, instanceCount);
                Array.Copy(animations, i, tempAnimations, 0, instanceCount);

                // Send the transform and animation data to the shader
                effect.Parameters["InstanceTransforms"].SetValue(tempTransforms);
                effect.Parameters["InstanceAnimations"].SetValue(tempAnimations);
                effect.CommitChanges();

                // Draw maxInstances copies of our geometry in a single batch.
                this.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                    part.BaseVertex, 0, part.NumVertices * instanceCount,
                    part.StartIndex, part.PrimitiveCount * instanceCount);
            }
        }
Esempio n. 30
0
        private void drawTexturedInstancedPrimitives(Matrix[] instancesArray, Effect effect, ModelMeshPart meshPart)
        {
            if (instancesArray.Length != 0)
            {
                instanceVertexBuffer.SetData(instancesArray, 0, instancesArray.Length, SetDataOptions.Discard);

                // Draw all the GRASS instance copies in a single call.
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                           meshPart.NumVertices, meshPart.StartIndex,
                                                           meshPart.PrimitiveCount, Math.Min(1048574, instancesArray.Length)); //TODO: should have warning or something when too big
                }
            }
        }
        /// <summary>
        /// Add model mesh part with the used effect to our sortedMeshes list.
        /// Neither the model mesh part nor the effect is directly used,
        /// we will extract all data from the model and only render the
        /// index and vertex buffers later.
        /// The model mesh part must use the TangentVertex format.
        /// </summary>
        /// <param name="vertexBuffer">Vertex buffer</param>
        /// <param name="indexBuffer">Index buffer</param>
        /// <param name="part">Part</param>
        /// <param name="effect">Effect</param>
        /// <returns>Renderable mesh</returns>
        public RenderableMesh Add(VertexBuffer vertexBuffer,
			IndexBuffer indexBuffer, ModelMeshPart part, Effect effect)
        {
            string techniqueName = effect.CurrentTechnique.Name;

            // Does this technique already exists?
            MeshesPerMaterialPerTechniques foundList = null;
            //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes)
            for (int listNum = 0; listNum < sortedMeshes.Count; listNum++)
            {
                MeshesPerMaterialPerTechniques list = sortedMeshes[listNum];

                if (list.technique != null &&
                    list.technique.Name == techniqueName)
                {
                    foundList = list;
                    break;
                } // if (list.technique.Name)
            } // for (listNum)

            // Did not found list? Create new one
            if (foundList == null)
            {
                EffectTechnique technique =
                    BaseGame.ParallaxShader.GetTechnique(techniqueName);

                // Make sure we always have a valid technique
                if (technique == null)
                {
                    if (BaseGame.CanUsePS20)
                        techniqueName = "Diffuse20";//"Specular20";
                    else
                        techniqueName = "Diffuse";//"Specular";
                    technique = BaseGame.ParallaxShader.GetTechnique(techniqueName);
                } // if

                foundList = new MeshesPerMaterialPerTechniques(technique);
                sortedMeshes.Add(foundList);
            } // if (foundList)

            // Create new material from the current effect parameters.
            // This will create duplicate materials if the same material is used
            // multiple times, we check this later.
            Material material = new Material(effect);

            // Search for material inside foundList.
            //obs: foreach (MeshesPerMaterial innerList in foundList.meshesPerMaterials)
            for (int innerListNum = 0; innerListNum <
                foundList.meshesPerMaterials.Count; innerListNum++)
            {
                MeshesPerMaterial innerList =
                    foundList.meshesPerMaterials[innerListNum];

                // Check if this is the same material and we can use it instead.
                // For our purposes it is sufficiant if we check textures and colors.
                if (innerList.material.diffuseTexture == material.diffuseTexture &&
                    innerList.material.normalTexture == material.normalTexture &&
                    innerList.material.ambientColor == material.ambientColor &&
                    innerList.material.diffuseColor == material.diffuseColor &&
                    innerList.material.specularColor == material.specularColor &&
                    innerList.material.specularPower == material.specularPower)
                {
                    // Reuse this material and quit this search
                    material = innerList.material;
                    break;
                } // if (innerList.material.diffuseTexture)
            } // foreach (innerList)

            // Build new RenderableMesh object
            RenderableMesh mesh = new RenderableMesh(
                vertexBuffer, indexBuffer, material, foundList.technique,
                part.VertexDeclaration,
                part.StreamOffset, part.VertexStride, part.BaseVertex,
                part.NumVertices, part.StartIndex, part.PrimitiveCount);
            foundList.Add(mesh);
            return mesh;
        }
Esempio n. 32
0
 public ModelExtractor(ModelMeshPart mmp, Vector3[] vecArray, VertexPositionTexture[] vpcVertexArray)
 {
     this.model = mmp;
     this.vectorArray = vecArray;
     this.vpcVerts = vpcVertexArray;
 }