예제 #1
1
파일: frmMain.cs 프로젝트: zulis/Sandbox
        private void SaveX(TVMesh tvm, string fileName)
        {
            ExtendedMaterial[] exMaterials = new ExtendedMaterial[tvm.GetGroupCount()];
            Material dxMaterial;
            int idx = 0;

            for (int group = 0; group < tvm.GetGroupCount(); group++)
            {
                idx = tvm.GetMaterial(group);
                dxMaterial = new Material();
                dxMaterial.AmbientColor = ToDx(core.MaterialFactory.GetAmbient(idx));
                dxMaterial.DiffuseColor = ToDx(core.MaterialFactory.GetDiffuse(idx));
                dxMaterial.EmissiveColor = ToDx(core.MaterialFactory.GetEmissive(idx));
                dxMaterial.SpecularColor = ToDx(core.MaterialFactory.GetSpecular(idx));
                dxMaterial.SpecularSharpness = core.MaterialFactory.GetPower(idx);
                exMaterials[group].Material3D = dxMaterial;
                // Get the Texture Filename.
                idx = tvm.GetTexture(group);
                // Add em to the array.
                exMaterials[group].TextureFilename = core.TextureFactory.GetTextureInfo(idx).Name;
            }

            // Save the Mesh.
            Microsoft.DirectX.Direct3D.Mesh dxMesh = new Microsoft.DirectX.Direct3D.Mesh(core.InternalObjects.GetD3DMesh(tvm.GetIndex()));
            int[] adjacency = new int[dxMesh.NumberFaces * 3];
            dxMesh.GenerateAdjacency(0f, adjacency);
            dxMesh.Save(fileName, adjacency, exMaterials, XFileFormat.Text);
        }
예제 #2
0
        private ExtendedMaterial[] InitMaterialArray(Dictionary <IPXVertex, int> vDic)
        {
            ExtendedMaterial[] ExMaterialArray = new ExtendedMaterial[Pmx.Material.Count];
            ARangeArray     = new AttributeRange[Pmx.Material.Count];
            ExMaterialArray = new ExtendedMaterial[Pmx.Material.Count];
            int faceOffset = 0;

            for (int i = 0; i < Pmx.Material.Count; i++)
            {
                IPXMaterial m = Pmx.Material[i];
                ARangeArray[i] = new AttributeRange
                {
                    AttribId    = i,
                    FaceCount   = m.Faces.Count,
                    FaceStart   = faceOffset,
                    VertexCount = VIndices[i].Count,
                    VertexStart = vDic[m.Faces[0].Vertex1]
                };
                faceOffset        += m.Faces.Count;
                ExMaterialArray[i] = new ExtendedMaterial
                {
                    MaterialD3D = new Material
                    {
                        //Ambient = new Color4(1,m.Ambient.R,m.Ambient.G,m.Ambient.B),
                        Emissive = new Color4(1, m.Ambient.R, m.Ambient.G, m.Ambient.B),
                        Diffuse  = m.Diffuse.ToColor4(),
                        Power    = m.Power,
                        Specular = new Color4(m.Specular.ToColor3())
                    },
                    TextureFileName = m.Tex
                };
            }
            return(ExMaterialArray);
        }
예제 #3
0
        private void CacheMaterials(aiMaterialVector materials)
        {
            var numMaterials = materials.Count;

            materialCache = new ExtendedMaterial[numMaterials];
            textureCache  = new Dictionary <string, Texture>();

            for (int i = 0; i < numMaterials; ++i)
            {
                var material           = materials[i];
                var dxExtendedMaterial = new ExtendedMaterial();
                var dxMaterial         = new Material();
                dxMaterial.AmbientColor            = material.Ambient.ToColorValue();
                dxMaterial.DiffuseColor            = material.Diffuse.ToColorValue();
                dxMaterial.EmissiveColor           = material.Emissive.ToColorValue();
                dxMaterial.SpecularColor           = material.Specular.ToColorValue();
                dxMaterial.SpecularSharpness       = material.ShininessStrength;
                dxExtendedMaterial.Material3D      = dxMaterial;
                dxExtendedMaterial.TextureFilename = material.TextureDiffuse0;

                materialCache[i] = dxExtendedMaterial;

                var textureFilename = dxExtendedMaterial.TextureFilename;
                if (!string.IsNullOrEmpty(textureFilename) && !textureCache.ContainsKey(textureFilename))
                {
                    textureCache.Add(textureFilename, CreateTexture(textureFilename));
                }
            }
        }
예제 #4
0
        public override Result Render(PMXMesh pmx)
        {
            Device device = swapChain.Device;

            device.SetRenderTarget(0, swapChain.GetBackBuffer(0));
            device.SetRenderState(RenderState.ZEnable, true);
            device.DepthStencilSurface = depthSurface;
            device.Viewport            = Viewport;
            //    device.SetRenderState(RenderState.Lighting, true);
            //    device.SetLight(0, pmx.MatManager.Light);
            //    device.EnableLight(0, true);
            device.SetTransform(TransformState.World, Camera.World);
            device.SetTransform(TransformState.View, Camera.View);
            device.SetTransform(TransformState.Projection, Camera.Projection);
            Sprite texSprite = pmx.TexSprite;

            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, pmx.MatManager.BGColor, 1.0f, 0);
            device.BeginScene();
            texSprite.Begin(SpriteFlags.ObjectSpace);
            //texSprite.Begin(SpriteFlags.None);
            Vector3 Pos = Vector3.Zero;

            for (int i = 0; i < pmx.Pmx.Material.Count; i++)
            //for (int i = 0; i < 1; i++)
            {
                ExtendedMaterial m   = pmx.GetMaterials()[i];
                Texture          tex = pmx.MatManager.DicObjTex[m.TextureFileName];
                int    width         = tex.GetLevelDescription(0).Width;
                int    height        = tex.GetLevelDescription(0).Height;
                Matrix scaling       = Matrix.Scaling(new Vector3(1.0f / width, 1.0f / height, 1.0f));
                Matrix transpose     = Matrix.Translation(Pos);
                texSprite.Transform = scaling * transpose;
                texSprite.Draw(tex, Color.White);
                if (i % 7 == 6)
                {
                    Pos.X  = 0;
                    Pos.Y += 1;
                }
                else
                {
                    Pos.X += 1;
                }
            }
            texSprite.End();
            pmx.EffectManager.SetMatrix(Camera);
            pmx.EffectManager.BeginUVTec();
            for (int p = 0; p < 1; p++)
            {
                pmx.EffectManager.BeginPass(p);
                for (int i = 0; i < pmx.Pmx.Material.Count; i++)
                {
                    pmx.DrawSubset(i);
                }
                pmx.EffectManager.EndPass();
            }
            pmx.EffectManager.EndTec();
            device.EndScene();
            return(swapChain.Present(Present.None));
        }
예제 #5
0
        public void SolidColorBrush()
        {
            var brush = new SolidColorBrush {
                Color = Color.Red
            };
            ExtendedMaterial res = brush.Convert(_converter);

            CheckColorsEqual(brush.Color, res.MaterialD3D.Diffuse);
            ExtendedMaterial res2 = new SolidColorBrush {
                Color = Color.Yellow
            }.Convert(_converter);

            CheckMaterial(Color.Yellow, res2.MaterialD3D);
        }
예제 #6
0
        public void LoadTest()
        {
            var sw = new Stopwatch();

            sw.Start();
            for (int i = 0; i < 1000000; i++)
            {
                var brush = new SolidColorBrush
                {
                    Color = GetRandomColor()
                };
                ExtendedMaterial res = brush.Convert(_converter);
                CheckColorsEqual(brush.Color, res.MaterialD3D.Diffuse);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
        }
        public override MeshContainer CreateMeshContainer(string name, MeshData meshData, ExtendedMaterial[] materials, EffectInstance[] effectInstances, int[] adjacency, SkinInfo skinInfo)
        {
            CustomMeshContainer meshContainer = new CustomMeshContainer();
            meshContainer.Name = name;
            meshContainer.MeshData = meshData;

            meshContainer.SetAdjacency(adjacency);
            meshContainer.SetEffects(effectInstances);

            meshContainer.SkinInfo = skinInfo;
            meshContainer.OriginalMesh = meshData.Mesh.Clone(meshData.Mesh.Device, meshData.Mesh.CreationOptions, meshData.Mesh.VertexFormat);

            if (skinInfo != null)
            {
                meshContainer.BoneOffsets = new Matrix[skinInfo.BoneCount];
                for (int i = 0; i < skinInfo.BoneCount; i++)
                    meshContainer.BoneOffsets[i] = skinInfo.GetBoneOffsetMatrix(i);
                meshContainer.PaletteEntries = Math.Min(MaxMatrices, meshContainer.SkinInfo.BoneCount);

                int influences;
                BoneCombination[] boneCombinations;

                meshContainer.MeshData.Mesh.Dispose();
                meshContainer.MeshData = new MeshData(meshContainer.SkinInfo.ConvertToIndexedBlendedMesh(meshContainer.OriginalMesh, meshContainer.PaletteEntries,
                    adjacency, out influences, out boneCombinations));
                meshContainer.Influences = influences;
                meshContainer.BoneCombinations = boneCombinations;

                VertexElement[] elements = meshContainer.MeshData.Mesh.GetDeclaration();
                for (int i = 0; i < elements.Length; i++)
                {
                    if (elements[i].Stream == 0xff)
                        break;

                    if (elements[i].Usage == DeclarationUsage.BlendIndices && elements[i].UsageIndex == 0)
                        elements[i].Type = DeclarationType.Color;
                }

                meshContainer.MeshData.Mesh.UpdateSemantics(elements);
            }

            return meshContainer;
        }
예제 #8
0
        public virtual Result Render(PMXMesh pmx)
        {
            Device device = swapChain.Device;

            device.SetRenderTarget(0, swapChain.GetBackBuffer(0));

            device.SetRenderState(RenderState.ZEnable, true);
            device.DepthStencilSurface = depthSurface;
            device.Viewport            = Viewport;
            device.SetRenderState(RenderState.Lighting, true);
            device.SetLight(0, pmx.MatManager.Light);
            device.EnableLight(0, true);
            device.SetTransform(TransformState.World, Camera.World);
            device.SetTransform(TransformState.View, Camera.View);
            device.SetTransform(TransformState.Projection, Camera.Projection);


            //アルファブレンド
            device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
            device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
            device.SetRenderState(RenderState.AlphaBlendEnable, true);

            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, pmx.MatManager.BGColor, 1.0f, 0);
            device.BeginScene();
            for (int i = 0; i < pmx.Pmx.Material.Count; i++)
            {
                ExtendedMaterial m = pmx.GetMaterials()[i];
                device.Material = m.MaterialD3D;
                device.SetTexture(0, pmx.MatManager.DicObjTex[m.TextureFileName]);
                if (pmx.Pmx.Material[i].BothDraw)
                {
                    device.SetRenderState(RenderState.CullMode, Cull.None);
                }
                else
                {
                    device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
                }
                pmx.DrawSubset(i);
            }
            device.EndScene();
            return(swapChain.Present(Present.None));
        }
예제 #9
0
        private static ExtendedMaterial[] GetMaterialsFromBrushes(Device device, Color defaultColor, DirectXModel m, IPlaneBrush[] brushesInOrder)
        {
            var materials = new ExtendedMaterial[brushesInOrder.Length];
            var converter = new DirectXBrushConverter(device);

            for (int i = 0; i < materials.Length; i++)
            {
                materials[i] = defaultColor.GetDirectXMaterial();
                if (brushesInOrder[i] == null)
                {
                    continue;
                }
                Texture texture;
                materials[i] = converter.TryConvert(brushesInOrder[i], out texture);
                if (texture != null)
                {
                    m.Textures[i] = texture;
                }
            }
            return(materials);
        }
예제 #10
0
 private Texture LoadTexture(Device device,
                             ExtendedMaterial mtrl,
                             string texturesPath,
                             Dictionary <string, string> customTextureNames)
 {
     if (mtrl.TextureFilename != null && mtrl.TextureFilename != String.Empty)
     {
         string texturefileName = mtrl.TextureFilename;
         if (customTextureNames != null)
         {
             string customTextureName = customTextureNames[texturefileName];
             if (customTextureName != null)
             {
                 texturefileName = customTextureName;
             }
         }
         if (texturesPath != null)
         {
             texturefileName = texturesPath + texturefileName;
         }
         return(TextureLoader.FromFile(device, texturefileName));
     }
     return(null);
 }
예제 #11
0
        private AnimationFrame CreateFrame(odfFrame frame, odfParser parser, HashSet<int> extractFrames, HashSet<int> meshIDs, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();
            animationFrame.Name = frame.Name;
            animationFrame.TransformationMatrix = frame.Matrix;
            animationFrame.OriginalTransform = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix;

            if ((int)frame.MeshId != 0 && meshIDs.Contains((int)frame.MeshId))
            {
                odfMesh mesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection);
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.Count];

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < mesh.Count; i++)
                {
                    odfSubmesh submesh = mesh[i];
                    List<odfFace> faceList = submesh.FaceList;
                    List<odfVertex> vertexList = submesh.VertexList;

                    odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                    bool skinned = boneList != null;
                    int numBones = skinned ? boneList.Count : 0;
                    string[] boneNames = new string[numBones];
                    Matrix[] boneOffsets = new Matrix[numBones];
                    for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                    {
                        odfBone bone = boneList[boneIdx];
                        boneNames[boneIdx] = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                        Matrix mirrored;
                        if (!BoneMatrixDic.TryGetValue(boneNames[boneIdx], out mirrored))
                        {
            #if !DONT_MIRROR
                            Vector3 translate, scale;
                            Quaternion rotate;
                            bone.Matrix.Decompose(out scale, out rotate, out translate);
                            mirrored = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate);
            #else
                            mirrored = bone.Matrix;
            #endif
                            BoneMatrixDic.Add(boneNames[boneIdx], mirrored);
                        }
                        boneOffsets[boneIdx] = mirrored;
                    }

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            ushort[] indices = faceList[j].VertexIndices;
                            indexStream.Write(indices[0]);
                            indexStream.Write(indices[1]);
                            indexStream.Write(indices[2]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        odfVertex vertex = vertexList[j];
            #if !DONT_MIRROR
                        Vector3 position = new Vector3(vertex.Position.X, vertex.Position.Y, -vertex.Position.Z);
                        Vector3 normal = new Vector3(vertex.Normal.X, vertex.Normal.Y, -vertex.Normal.Z);
            #else
                        Vector3 position = vertex.Position;
                        Vector3 normal = vertex.Normal;
            #endif
                        float[] boneWeights = vertexWeights[j];

                        normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertex.BoneIndices, Color.Yellow.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + (normal / 11), boneWeights, vertex.BoneIndices, Color.Blue.ToArgb());

                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name = animationFrame.Name;
                    meshContainer.MeshData = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i] = meshContainer;

                    odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient = mat.Ambient;
                        material3D.Diffuse = mat.Diffuse;
                        material3D.Emissive = mat.Emissive;
                        material3D.Specular = mat.Specular;
                        material3D.Power = mat.SpecularPower;
                        int matIdx = parser.MaterialSection.IndexOf(mat);
                        Materials[matIdx] = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = -1;
                        if ((int)submesh.TextureIds[0] != 0 && !TextureDic.TryGetValue((int)submesh.TextureIds[0], out texIdx))
                        {
                            odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[0], parser.TextureSection);
                            if (tex != null)
                            {
                                try
                                {
                                    odfTextureFile texFile = new odfTextureFile(null, Path.GetDirectoryName(parser.ODFPath) + Path.DirectorySeparatorChar + tex.TextureFile);
                                    int fileSize = 0;
                                    ImportedTexture impTex = new ImportedTexture(texFile.DecryptFile(ref fileSize).BaseStream, tex.TextureFile);
                                    Texture memTex = impTex.ToTexture(device);
                                    texIdx = TextureDic.Count;
                                    TextureDic.Add((int)submesh.TextureIds[0], texIdx);
                                    Textures[texIdx] = memTex;
                                }
                                catch (SlimDXException ex)
                                {
                                    Utility.ReportException(ex);
                                    Report.ReportLog("Please check " + tex.TextureFile + ". It may have an unsupported format.");
                                }
                                catch (Exception ex)
                                {
                                    Utility.ReportException(ex);
                                }
                            }
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                animationFrame.Bounds = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                odfFrame child = frame[i];
                if (extractFrames.Contains((int)child.Id))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshIDs, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return animationFrame;
        }
예제 #12
0
        // TODO: Create with XOF
        /// <summary>Create the materials for the mesh</summary>
        public void CreateMaterials(string folder, Device device, GraphicsStream adjacency, ExtendedMaterial[] materials)
        {
            // Does the mesh have materials?
            if ((materials != null) && (materials.Length > 0))
            {
                // Allocate the arrays for the materials
                meshMaterials = new Material[materials.Length];
                meshTextures = new BaseTexture[materials.Length];

                // Copy each material and create it's texture
                for(int i = 0; i < materials.Length; i++)
                {
                    // Copy the material first
                    meshMaterials[i] = materials[i].Material3D;

                    // Is there a texture for this material?
                    if ((materials[i].TextureFilename == null) || (materials[i].TextureFilename.Length == 0) )
                        continue; // No, just continue now

                    ImageInformation info = new ImageInformation();
                    string textureFile = folder + materials[i].TextureFilename;
                    try
                    {
                        // First look for the texture in the same folder as the input folder
                        info = TextureLoader.ImageInformationFromFile(textureFile);
                    }
                    catch
                    {
                        try
                        {
                            // Couldn't find it, look in the media folder
                            textureFile = Utility.FindMediaFile(materials[i].TextureFilename);
                            info = TextureLoader.ImageInformationFromFile(textureFile);
                        }
                        catch (MediaNotFoundException)
                        {
                            // Couldn't find it anywhere, skip it
                            continue;
                        }
                    }
                    switch (info.ResourceType)
                    {
                        case ResourceType.Textures:
                            meshTextures[i] = TextureLoader.FromFile(device, textureFile);
                            break;
                        case ResourceType.CubeTexture:
                            meshTextures[i] = TextureLoader.FromCubeFile(device, textureFile);
                            break;
                        case ResourceType.VolumeTexture:
                            meshTextures[i] = TextureLoader.FromVolumeFile(device, textureFile);
                            break;
                    }
                }
            }
        }
예제 #13
0
        public void GetLists( ArrayList models, out Mesh[] meshes,  out Matrix[] localToWorlds, out int[][] adjacencies, out ExtendedMaterial[] materials, out EffectInstance[] effectInstances)
        {
            ArrayList meshList = new ArrayList();
            ArrayList localToWorldList = new ArrayList();
            ArrayList adjacenciesList = new ArrayList();
            ArrayList materialList = new ArrayList();
            ArrayList effectInstanceList = new ArrayList();

            foreach( OpsModel model in models)
            {
                OpsFrame.ComputeLocalToWorld( model.HierarchyRoot as OpsFrame , Matrix.Identity );

                foreach( OpsMeshContainer mc in model.GetMeshEnumerator())
                {
                    meshList.Add( mc.MeshData.Mesh );
                    adjacenciesList.Add( mc.GetAdjacency() );
                    localToWorldList.Add( mc.LocalToWorld );    

                    ExtendedMaterial[] oldMtlList = mc.GetMaterials();
                    EffectInstance[] oldFxList = mc.GetEffectInstances();
                
                    System.Diagnostics.Debug.Assert( oldMtlList.Length == oldFxList.Length );

                    materialList.AddRange( oldMtlList );
                    effectInstanceList.AddRange( oldFxList );
                }
            }

            meshes = meshList.ToArray( typeof(Mesh) ) as Mesh[];
            localToWorlds = localToWorldList.ToArray( typeof(Matrix) ) as Matrix[];
            adjacencies = adjacenciesList.ToArray( typeof(int[]) ) as int[][];
            materials = materialList.ToArray( typeof(ExtendedMaterial) ) as ExtendedMaterial[];
            effectInstances = effectInstanceList.ToArray( typeof(EffectInstance) ) as EffectInstance[];
        }
예제 #14
0
        private AnimationFrame CreateFrame(remBone frame, remParser parser, HashSet <string> extractFrames, remMesh mesh, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();

            animationFrame.Name = frame.name.ToString();
            animationFrame.TransformationMatrix = frame.matrix;
            animationFrame.OriginalTransform    = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform    = combinedParent * animationFrame.TransformationMatrix;

            if (frame.name == mesh.frame)
            {
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.numMats];

                List <List <remVertex> > submeshVertLists   = new List <List <remVertex> >(mesh.numMats);
                List <List <ushort> >    submeshFaceLists   = new List <List <ushort> >(mesh.numMats);
                List <int[]>             submeshVertIndices = new List <int[]>(mesh.numMats);
                SplitMesh(mesh, submeshVertLists, submeshFaceLists, submeshVertIndices);

                remSkin       boneList        = rem.FindSkin(mesh.name, parser.SKIC);
                bool          skinned         = boneList != null;
                int           numBones        = skinned ? boneList.Count : 0;
                List <string> boneNamesList   = new List <string>(numBones);
                List <Matrix> boneOffsetsList = new List <Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    boneNamesList.Add(boneList[boneIdx].bone.ToString());
                    boneOffsetsList.Add(boneList[boneIdx].matrix);
                }
                List <string> boneFrameParentNames    = new List <string>(numBones);
                List <Matrix> boneFrameParentMatrices = new List <Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    remBone boneFrame = rem.FindFrame(boneList[boneIdx].bone, parser.BONC.rootFrame);
                    if (boneFrame == null)
                    {
                        continue;
                    }
                    remBone boneFrameParent = boneFrame.Parent;
                    if (!boneNamesList.Contains(boneFrameParent.name) && !boneFrameParentNames.Contains(boneFrameParent.name))
                    {
                        boneFrameParentNames.Add(boneFrameParent.name);
                        Matrix incompleteMeshFrameCorrection = Matrix.Invert(frame.matrix);
                        boneFrameParentMatrices.Add(incompleteMeshFrameCorrection * Matrix.Invert(boneFrame.matrix) * boneList[boneIdx].matrix);
                    }
                }
                boneNamesList.AddRange(boneFrameParentNames);
                string[] boneNames = boneNamesList.ToArray();
                boneOffsetsList.AddRange(boneFrameParentMatrices);
                Matrix[] boneOffsets = boneOffsetsList.ToArray();

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[submeshFaceLists.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < submeshFaceLists.Count; i++)
                {
                    List <ushort>    faceList   = submeshFaceLists[i];
                    List <remVertex> vertexList = submeshVertLists[i];

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            indexStream.Write(faceList[j]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    byte[][]  vertexBoneIndices = null;
                    float[][] vertexWeights     = ConvertVertexWeights(vertexList, submeshVertIndices[i], boneList, out vertexBoneIndices);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, vertexBoneIndices, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        remVertex vertex      = vertexList[j];
                        Vector3   position    = vertex.Position;
                        Vector3   normal      = vertex.Normal;
                        float[]   boneWeights = vertexWeights[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(position, boneWeights, vertexBoneIndices[j], Color.Coral.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + normal, boneWeights, vertexBoneIndices[j], Color.Blue.ToArgb());

#if !DONT_MIRROR
                        position.Z *= -1f;
#endif
                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name        = animationFrame.Name;
                    meshContainer.MeshData    = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames   = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i]         = meshContainer;

                    remMaterial mat = rem.FindMaterial(mesh.materials[i], parser.MATC);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient  = new Color4(mat.ambient);
                        material3D.Diffuse  = new Color4(mat.diffuse);
                        material3D.Emissive = new Color4(mat.emissive);
                        material3D.Specular = new Color4(mat.specular);
                        material3D.Power    = mat.specularPower;
                        int matIdx = parser.MATC.IndexOf(mat);
                        Materials[matIdx]           = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = 0;
                        if (mat.texture != null && !TextureDic.TryGetValue(mat.texture.ToString(), out texIdx))
                        {
                            ImportedTexture importedTex = null;
                            if (!ImportedTextures.TryGetValue(mat.texture.ToString(), out importedTex))
                            {
                                importedTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                if (importedTex == null)
                                {
                                    Report.ReportLog("Export textures of TEXH.FPK!");
                                    continue;
                                }
                                ImportedTextures.Add(mat.texture.ToString(), importedTex);
                            }
                            Texture memTex = Texture.FromMemory(device, importedTex.Data);
                            texIdx = TextureDic.Count;
                            TextureDic.Add(mat.texture.ToString(), texIdx);
                            Textures.Add(memTex);
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform);
                max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform);
                animationFrame.Bounds        = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                remBone child = frame[i];
                if (extractFrames.Contains(child.name.ToString()))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, mesh, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return(animationFrame);
        }
        void SaveTexture(string filename)
        {
            //this.frames.Sort(FrameCompare);
            int     tWidth        = 1; // frames[0].avatar.Label.Image.Width;
            int     tHeight       = 1; // frames[0].avatar.Label.Image.Height;
            bool    flag          = true;
            Texture outputTexture = null;

            CustomVertex.PositionColoredTextured[] vertexes = new CustomVertex.PositionColoredTextured[4 * frames.Count];
            short[] indexes = new short[frames.Count * 6];
            for (int j = 0; j < frames.Count * 4; j++)
            {
                vertexes[j].Color    = Color.White.ToArgb();
                vertexes[j].Position = new Vector3(0, 0, 0);
            }
            //int maxWidth, maxHeight;
            if (frames.Count > 1)
            {
                while (flag)
                {
                    if (OTNode.wFlag)
                    {
                        tWidth += OTNode.widthNeed;
                    }
                    else
                    {
                        tHeight += OTNode.heightNeed;
                    }
                    //tWidth *= 2;
                    // tHeight *= 2;
                    if (outputTexture != null)
                    {
                        outputTexture.Dispose();
                    }
                    outputTexture = new Texture(d3dDevice, tWidth, tHeight, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
                    Surface outputTextureSurface = outputTexture.GetSurfaceLevel(0);
                    d3dDevice.ColorFill(outputTextureSurface, new Rectangle(0, 0, tWidth, tHeight), Color.Magenta);
                    OTNode.target = outputTextureSurface;
                    OTNode node = new OTNode(new Rectangle(0, 0, tWidth, tHeight));

                    //maxHeight = maxWidth = 0;
                    for (int i = 0; i < frames.Count; i++)
                    {
                        toolStripProgressBar1.Value = (int)((float)(i + 1) / frames.Count * 100);
                        this.Update();
                        Rectangle rect = node.Insert(frames[i]);
                        if (rect == Rectangle.Empty)
                        {
                            flag = true;
                            break;
                        }
                        else
                        {
                            flag = false;
                        }
                        //if (rect.Right > maxWidth)
                        //    maxWidth = rect.Right;
                        //if (rect.Bottom > maxHeight)
                        //    maxHeight = rect.Bottom;
                        vertexes[i * 4].X = -frames[i].centerPoint.X;
                        vertexes[i * 4].Y = frames[i].centerPoint.Y - frames[i].avatar.Label.Image.Height;

                        vertexes[i * 4 + 1].X = vertexes[i * 4].X;
                        vertexes[i * 4 + 1].Y = frames[i].centerPoint.Y;

                        vertexes[i * 4 + 2].X = frames[i].avatar.Label.Image.Width - frames[i].centerPoint.X;;
                        vertexes[i * 4 + 2].Y = vertexes[i * 4 + 1].Y;

                        vertexes[i * 4 + 3].X = vertexes[i * 4 + 2].X;
                        vertexes[i * 4 + 3].Y = vertexes[i * 4].Y;

                        vertexes[i * 4].Tu     = (rect.Left + 1) / (float)tWidth;
                        vertexes[i * 4].Tv     = (rect.Bottom - 1) / (float)tHeight;
                        vertexes[i * 4 + 1].Tu = vertexes[i * 4].Tu;
                        vertexes[i * 4 + 1].Tv = (rect.Top + 1) / (float)tHeight;
                        vertexes[i * 4 + 2].Tu = (rect.Right - 1) / (float)tWidth;
                        vertexes[i * 4 + 2].Tv = vertexes[i * 4 + 1].Tv;
                        vertexes[i * 4 + 3].Tu = vertexes[i * 4 + 2].Tu;
                        vertexes[i * 4 + 3].Tv = vertexes[i * 4].Tv;


                        indexes[i * 6 + 0] = (short)(i * 4 + 0); indexes[i * 6 + 1] = (short)(i * 4 + 1); indexes[i * 6 + 2] = (short)(i * 4 + 2);
                        indexes[i * 6 + 3] = (short)(i * 4 + 3); indexes[i * 6 + 4] = (short)(i * 4 + 0); indexes[i * 6 + 5] = (short)(i * 4 + 2);
                    }
                }
            }
            else
            {
                int i = 0;
                tWidth  = frames[0].avatar.Label.Image.Width;
                tHeight = frames[0].avatar.Label.Image.Height;
                Rectangle rect = new Rectangle(0, 0, frames[0].avatar.Label.Image.Width, frames[0].avatar.Label.Image.Height);
                vertexes[i * 4].X = -frames[i].centerPoint.X;
                vertexes[i * 4].Y = frames[i].centerPoint.Y - frames[i].avatar.Label.Image.Height;

                vertexes[i * 4 + 1].X = vertexes[i * 4].X;
                vertexes[i * 4 + 1].Y = frames[i].centerPoint.Y;

                vertexes[i * 4 + 2].X = frames[i].avatar.Label.Image.Width - frames[i].centerPoint.X;;
                vertexes[i * 4 + 2].Y = vertexes[i * 4 + 1].Y;

                vertexes[i * 4 + 3].X = vertexes[i * 4 + 2].X;
                vertexes[i * 4 + 3].Y = vertexes[i * 4].Y;

                vertexes[i * 4].Tu     = (rect.Left + 1) / (float)tWidth;
                vertexes[i * 4].Tv     = (rect.Bottom - 1) / (float)tHeight;
                vertexes[i * 4 + 1].Tu = vertexes[i * 4].Tu;
                vertexes[i * 4 + 1].Tv = (rect.Top + 1) / (float)tHeight;
                vertexes[i * 4 + 2].Tu = (rect.Right - 1) / (float)tWidth;
                vertexes[i * 4 + 2].Tv = vertexes[i * 4 + 1].Tv;
                vertexes[i * 4 + 3].Tu = vertexes[i * 4 + 2].Tu;
                vertexes[i * 4 + 3].Tv = vertexes[i * 4].Tv;


                indexes[i * 6 + 0] = (short)(i * 4 + 0); indexes[i * 6 + 1] = (short)(i * 4 + 1); indexes[i * 6 + 2] = (short)(i * 4 + 2);
                indexes[i * 6 + 3] = (short)(i * 4 + 3); indexes[i * 6 + 4] = (short)(i * 4 + 0); indexes[i * 6 + 5] = (short)(i * 4 + 2);

                outputTexture = frames[0].texture;
            }
            Mesh mesh = new Mesh(2 * frames.Count, 4 * frames.Count, MeshFlags.Managed, CustomVertex.PositionColoredTextured.Format, d3dDevice);

            mesh.SetVertexBufferData(vertexes, LockFlags.None);
            mesh.SetIndexBufferData(indexes, LockFlags.None);
            //---------------------------
            //Setting one of these does NOT work.  You MUST set both.
            AttributeRange[] attributeTable = new AttributeRange[frames.Count];
            int[]            attributes     = mesh.LockAttributeBufferArray(LockFlags.None);
            for (int i = 0; i < frames.Count; i++)
            {
                attributes[i * 2]             = i;
                attributes[i * 2 + 1]         = i;
                attributeTable[i].AttributeId = i;  //ID is the value passed into the DrawSubset function of Mesh.
                attributeTable[i].FaceCount   = 2;  //Our subsets only have 1 face.
                attributeTable[i].FaceStart   = i * 2;
                attributeTable[i].VertexCount = 4;  //We need 3 vertices to make a face.
                attributeTable[i].VertexStart = i * 4;
            }
            mesh.UnlockAttributeBuffer(attributes);
            mesh.SetAttributeTable(attributeTable);
            //---------------------------
            ExtendedMaterial[] em = new ExtendedMaterial[frames.Count];
            em[0].TextureFilename = System.IO.Path.GetFileNameWithoutExtension(filename) + ".dds";
            for (int i = 0; i < frames.Count; i++)
            {
                Material mat = new Material();
                mat.Diffuse      = Color.White;
                mat.Ambient      = mat.Diffuse;
                mat.Specular     = mat.Diffuse;
                mat.Emissive     = Color.Black;
                em[i].Material3D = mat;
            }
            mesh.Save(System.IO.Path.GetFileNameWithoutExtension(filename) + ".sht", (int[])null, em, null, XFileFormat.Binary);
            TextureLoader.Save(System.IO.Path.GetFileNameWithoutExtension(filename) + ".dds", ImageFileFormat.Dds, outputTexture);
        }
예제 #16
0
            //AllocateHierarchy
            public override MeshContainer CreateMeshContainer(
                string name,
                MeshData meshData,
                ExtendedMaterial[] materials,
                EffectInstance[] effectInstances,
                GraphicsStream adjacency,
                SkinInformation skinInfo)
            { 
                if(meshData.Mesh == null )
                    throw new OpsException("Expecting Microsoft.DirectX.Direct3D.Mesh not Microsoft.DirectX.Direct3D.ProgressiveMesh or Microsoft.DirectX.Direct3D.PatchMesh.");

                OpsMeshContainer mc= new OpsMeshContainer();
                mc.Name= name;
                mc.MeshData= meshData;
                mc.SetMaterials(materials);
                mc.SetEffectInstances(effectInstances);
                mc.SetAdjacency(adjacency);
                mc.SkinInformation = skinInfo;

                return mc;
            }    
예제 #17
0
        private AnimationFrame CreateFrame(remBone frame, remParser parser, HashSet<string> extractFrames, remMesh mesh, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();
            animationFrame.Name = frame.name.ToString();
            animationFrame.TransformationMatrix = frame.matrix;
            animationFrame.OriginalTransform = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix;

            if (frame.name == mesh.frame)
            {
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.numMats];

                List<List<remVertex>> submeshVertLists = new List<List<remVertex>>(mesh.numMats);
                List<List<ushort>> submeshFaceLists = new List<List<ushort>>(mesh.numMats);
                List<int[]> submeshVertIndices = new List<int[]>(mesh.numMats);
                SplitMesh(mesh, submeshVertLists, submeshFaceLists, submeshVertIndices);

                remSkin boneList = rem.FindSkin(mesh.name, parser.SKIC);
                bool skinned = boneList != null;
                int numBones = skinned ? boneList.Count : 0;
                List<string> boneNamesList = new List<string>(numBones);
                List<Matrix> boneOffsetsList = new List<Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    boneNamesList.Add(boneList[boneIdx].bone.ToString());
                    boneOffsetsList.Add(boneList[boneIdx].matrix);
                }
                List<string> boneFrameParentNames = new List<string>(numBones);
                List<Matrix> boneFrameParentMatrices = new List<Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    remBone boneFrame = rem.FindFrame(boneList[boneIdx].bone, parser.BONC.rootFrame);
                    if (boneFrame == null)
                    {
                        continue;
                    }
                    remBone boneFrameParent = boneFrame.Parent;
                    if (!boneNamesList.Contains(boneFrameParent.name) && !boneFrameParentNames.Contains(boneFrameParent.name))
                    {
                        boneFrameParentNames.Add(boneFrameParent.name);
                        Matrix incompleteMeshFrameCorrection = Matrix.Invert(frame.matrix);
                        boneFrameParentMatrices.Add(incompleteMeshFrameCorrection * Matrix.Invert(boneFrame.matrix) * boneList[boneIdx].matrix);
                    }
                }
                boneNamesList.AddRange(boneFrameParentNames);
                string[] boneNames = boneNamesList.ToArray();
                boneOffsetsList.AddRange(boneFrameParentMatrices);
                Matrix[] boneOffsets = boneOffsetsList.ToArray();

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[submeshFaceLists.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < submeshFaceLists.Count; i++)
                {
                    List<ushort> faceList = submeshFaceLists[i];
                    List<remVertex> vertexList = submeshVertLists[i];

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            indexStream.Write(faceList[j]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    byte[][] vertexBoneIndices = null;
                    float[][] vertexWeights = ConvertVertexWeights(vertexList, submeshVertIndices[i], boneList, out vertexBoneIndices);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, vertexBoneIndices, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        remVertex vertex = vertexList[j];
                        Vector3 position = vertex.Position;
                        Vector3 normal = vertex.Normal;
                        float[] boneWeights = vertexWeights[j];

                        normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertexBoneIndices[j], Color.Coral.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + normal, boneWeights, vertexBoneIndices[j], Color.Blue.ToArgb());

            #if !DONT_MIRROR
                        position.Z *= -1f;
            #endif
                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name = animationFrame.Name;
                    meshContainer.MeshData = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i] = meshContainer;

                    remMaterial mat = rem.FindMaterial(mesh.materials[i], parser.MATC);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient = new Color4(mat.ambient);
                        material3D.Diffuse = new Color4(mat.diffuse);
                        material3D.Emissive = new Color4(mat.emissive);
                        material3D.Specular = new Color4(mat.specular);
                        material3D.Power = mat.specularPower;
                        int matIdx = parser.MATC.IndexOf(mat);
                        Materials[matIdx] = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = 0;
                        if (mat.texture != null && !TextureDic.TryGetValue(mat.texture.ToString(), out texIdx))
                        {
                            ImportedTexture importedTex = null;
                            if (!ImportedTextures.TryGetValue(mat.texture.ToString(), out importedTex))
                            {
                                importedTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                if (importedTex == null)
                                {
                                    Report.ReportLog("Export textures of TEXH.FPK!");
                                    continue;
                                }
                                ImportedTextures.Add(mat.texture.ToString(), importedTex);
                            }
                            Texture memTex = Texture.FromMemory(device, importedTex.Data);
                            texIdx = TextureDic.Count;
                            TextureDic.Add(mat.texture.ToString(), texIdx);
                            Textures.Add(memTex);
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform);
                max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform);
                animationFrame.Bounds = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                remBone child = frame[i];
                if (extractFrames.Contains(child.name.ToString()))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, mesh, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return animationFrame;
        }
예제 #18
0
        /// <summary>
        /// Constructor, called by HierarchyAllocator
        /// </summary>
        /// <param name="subfolder">textures are found in ../Cells/subfolder, where subfolder is the cell group name</param>
        /// <param name="name">mesh name (read from the X file)</param>
        /// <param name="mesh">the source mesh (as a standard mesh)</param>
        /// <param name="extmaterials">Materials and texture filenames</param>
        /// <param name="effectInstances">Effects</param>
        /// <param name="adjacency">Mesh adjacency data</param>
        /// <param name="skinInfo">Skin information for the mesh</param>
        public Cytoplasm(
            string subfolder,
            string name,
            Mesh mesh,
            ExtendedMaterial[] extmaterials,
            EffectInstance[] effectInstances,
            GraphicsStream adjacency,
            SkinInformation skinInfo)
        {
            // Store the name
            Name = name;

            // Keep the original mesh because this is needed for MousePick()
            // (ProgressiveMeshes don't have a .Intersect() method)
            originalMesh = mesh;

            // Store the materials
            int matlength = 0;
            if (extmaterials != null)
                matlength = extmaterials.Length;
            materials = new Material[matlength];
            textures = new Texture[matlength];
            bumps = new Texture[matlength];
            for (int i = 0; i < matlength; i++)
            {
                materials[i] = extmaterials[i].Material3D;
                // TRUESPACE HACK: Truespace doesn't allow me to set any ambient values in materials,
                // which means that everything comes out black if it isn't lit by the diffuse light.
                // So add a default ambient value here for any black cells, to simulate reflection from terrain
                if ((materials[i].Ambient.R + materials[i].Ambient.G + materials[i].Ambient.B) == 0)
                    materials[i].Ambient = Color.FromArgb(68, 68, 68);

                if ((extmaterials[i].TextureFilename != null) && (extmaterials[i].TextureFilename !=
                    string.Empty))
                {
                    try
                    {
                        // We have a texture file, rather than an inline texture, so try to load it from ./cells/group/type
                        textures[i] = TextureLoader.FromFile(Engine.Device,
                            FileResource.Fsp(subfolder, extmaterials[i].TextureFilename));
                        // Also attempt to load a normal map, if any
                        try
                        {
                            string filename = System.IO.Path.GetFileNameWithoutExtension(extmaterials[i].TextureFilename) + " Normal.PNG";
                            bumps[i] = TextureLoader.FromFile(Engine.Device,
                                FileResource.Fsp(subfolder, filename));
                        }
                        catch { }
                    }
                    catch
                    {
                        throw new SDKException("Failed to load texture " + FileResource.Fsp(subfolder, extmaterials[i].TextureFilename));
                    }
                }
            }

            // Get access to the vertices to allow various operations
            // get the input vertices as an array (in case I want to modify them)
            VertexBuffer vb = mesh.VertexBuffer;						// Retrieve the vertex buffer data
            System.Array vert = null;                                   // We don't know if array will be PositionNormal or PositionNormalTextured, so use generic type

            if (mesh.VertexFormat == VertexFormats.PositionNormal)
            {
                vert = vb.Lock(0,
                    typeof(CustomVertex.PositionNormal),
                    LockFlags.ReadOnly,
                    mesh.NumberVertices);
            }
            else
            {
                vert = vb.Lock(0,
                    typeof(CustomVertex.PositionNormalTextured),
                    LockFlags.ReadOnly,
                    mesh.NumberVertices);
            }

            // compute the bounding sphere radius & centre from the vertices
            // NOTE: THIS VALUE IS FOR THE UNSCALED VERTICES and needs to be transformed by the combined transformation matrix
            boundRadius = Geometry.ComputeBoundingSphere(vert,
                                                            mesh.VertexFormat,
                                                            out boundCentre);

            // Calculate a bounding box for fine collision detection
            // NOTE: THIS VALUE IS FOR THE UNSCALED VERTICES and needs to be transformed by the combined transformation matrix
            Geometry.ComputeBoundingBox(vert, mesh.VertexFormat, out minOBB, out maxOBB);

            // gather useful debug info while we have the vertices
            //			Debug.WriteLine(String.Format("		Loaded mesh [{0}] from disk. {1} vertices, {2} textures, {3} materials",
            //											name,md.Mesh.NumberVertices,textures.Length, materials.Length));
            //						Debug.WriteLine(String.Format("Mesh is centred on {0} with bound radius {1}; OBB is {2}:{3}",
            //											boundcentre, boundradius, OBBmin, OBBmax));

            vb.Unlock();
            vb.Dispose();														// vertices no longer needed

            // create a cleaned progressive mesh from the input
            using (Mesh clean = Mesh.Clean(CleanType.Optimization, mesh, adjacency, adjacency))
            {
                // From the cleaned mesh, create one that has binormals and tangents as well as normals
                // (ThreeDee.BinormalVertex). These are needed for normal mapping in the shader
                using (Mesh clone = clean.Clone(MeshFlags.Managed, BinormalVertex.VertexElements, Engine.Device))
                {
                    // Add tangents and binormals
                    clone.ComputeTangent(0, 0, 0, 0);
                    //clone.ComputeTangentFrame(0);

                    // Create a new progressive mesh from the clean version
                    MeshData md = new MeshData();
                    md.ProgressiveMesh = new ProgressiveMesh(clone,
                                                                adjacency,
                                                                null,
                                                                12,					// min acceptable # faces
                                                                MeshFlags.SimplifyFace);
                    this.MeshData = md;
                }

            }

            // Add a device reset handler to reload resources (if required)
            /////Engine.Device.DeviceReset += new System.EventHandler(OnReset);
        }
예제 #19
0
        private AnimationFrame CreateFrame(odfFrame frame, odfParser parser, HashSet <int> extractFrames, HashSet <int> meshIDs, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();

            animationFrame.Name = frame.Name;
            animationFrame.TransformationMatrix = frame.Matrix;
            animationFrame.OriginalTransform    = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform    = combinedParent * animationFrame.TransformationMatrix;

            if ((int)frame.MeshId != 0 && meshIDs.Contains((int)frame.MeshId))
            {
                odfMesh            mesh      = odf.FindMeshListSome(frame.MeshId, parser.MeshSection);
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.Count];

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < mesh.Count; i++)
                {
                    odfSubmesh       submesh    = mesh[i];
                    List <odfFace>   faceList   = submesh.FaceList;
                    List <odfVertex> vertexList = submesh.VertexList;

                    odfBoneList boneList    = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                    bool        skinned     = boneList != null;
                    int         numBones    = skinned ? boneList.Count : 0;
                    string[]    boneNames   = new string[numBones];
                    Matrix[]    boneOffsets = new Matrix[numBones];
                    for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                    {
                        odfBone bone = boneList[boneIdx];
                        boneNames[boneIdx] = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                        Matrix mirrored;
                        if (!BoneMatrixDic.TryGetValue(boneNames[boneIdx], out mirrored))
                        {
#if !DONT_MIRROR
                            Vector3    translate, scale;
                            Quaternion rotate;
                            bone.Matrix.Decompose(out scale, out rotate, out translate);
                            mirrored = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate);
#else
                            mirrored = bone.Matrix;
#endif
                            BoneMatrixDic.Add(boneNames[boneIdx], mirrored);
                        }
                        boneOffsets[boneIdx] = mirrored;
                    }

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            ushort[] indices = faceList[j].VertexIndices;
                            indexStream.Write(indices[0]);
                            indexStream.Write(indices[1]);
                            indexStream.Write(indices[2]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        odfVertex vertex = vertexList[j];
#if !DONT_MIRROR
                        Vector3 position = new Vector3(vertex.Position.X, vertex.Position.Y, -vertex.Position.Z);
                        Vector3 normal   = new Vector3(vertex.Normal.X, vertex.Normal.Y, -vertex.Normal.Z);
#else
                        Vector3 position = vertex.Position;
                        Vector3 normal   = vertex.Normal;
#endif
                        float[] boneWeights = vertexWeights[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(position, boneWeights, vertex.BoneIndices, Color.Yellow.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + (normal / 11), boneWeights, vertex.BoneIndices, Color.Blue.ToArgb());

                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name        = animationFrame.Name;
                    meshContainer.MeshData    = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames   = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i]         = meshContainer;

                    odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient  = mat.Ambient;
                        material3D.Diffuse  = mat.Diffuse;
                        material3D.Emissive = mat.Emissive;
                        material3D.Specular = mat.Specular;
                        material3D.Power    = mat.SpecularPower;
                        int matIdx = parser.MaterialSection.IndexOf(mat);
                        Materials[matIdx]           = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = -1;
                        if ((int)submesh.TextureIds[0] != 0 && !TextureDic.TryGetValue((int)submesh.TextureIds[0], out texIdx))
                        {
                            odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[0], parser.TextureSection);
                            if (tex != null)
                            {
                                try
                                {
                                    odfTextureFile  texFile  = new odfTextureFile(null, Path.GetDirectoryName(parser.ODFPath) + Path.DirectorySeparatorChar + tex.TextureFile);
                                    int             fileSize = 0;
                                    ImportedTexture impTex   = new ImportedTexture(texFile.DecryptFile(ref fileSize).BaseStream, tex.TextureFile);
                                    Texture         memTex   = impTex.ToTexture(device);
                                    texIdx = TextureDic.Count;
                                    TextureDic.Add((int)submesh.TextureIds[0], texIdx);
                                    Textures[texIdx] = memTex;
                                }
                                catch (SlimDXException ex)
                                {
                                    Utility.ReportException(ex);
                                    Report.ReportLog("Please check " + tex.TextureFile + ". It may have an unsupported format.");
                                }
                                catch (Exception ex)
                                {
                                    Utility.ReportException(ex);
                                }
                            }
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                animationFrame.Bounds        = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                odfFrame child = frame[i];
                if (extractFrames.Contains((int)child.Id))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshIDs, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return(animationFrame);
        }
예제 #20
0
        private void CacheMaterials(aiMaterialVector materials)
        {
            var numMaterials = materials.Count;
            materialCache = new ExtendedMaterial[numMaterials];
            textureCache = new Dictionary<string, Texture>();

            for (int i = 0; i < numMaterials; ++i) {
                var material = materials[i];
                var dxExtendedMaterial = new ExtendedMaterial();
                var dxMaterial = new Material();
                dxMaterial.AmbientColor = material.Ambient.ToColorValue();
                dxMaterial.DiffuseColor = material.Diffuse.ToColorValue();
                dxMaterial.EmissiveColor = material.Emissive.ToColorValue();
                dxMaterial.SpecularColor = material.Specular.ToColorValue();
                dxMaterial.SpecularSharpness = material.ShininessStrength;
                dxExtendedMaterial.Material3D = dxMaterial;
                dxExtendedMaterial.TextureFilename = material.TextureDiffuse0;

                materialCache[i] = dxExtendedMaterial;

                var textureFilename = dxExtendedMaterial.TextureFilename;
                if (!string.IsNullOrEmpty(textureFilename) && !textureCache.ContainsKey(textureFilename)) {
                    textureCache.Add(textureFilename, CreateTexture(textureFilename));
                }
            }
        }
예제 #21
0
		private static ExtendedMaterial[] GetMaterialsFromBrushes(Device device, Color defaultColor, DirectXModel m, IPlaneBrush[] brushesInOrder)
		{
			var materials = new ExtendedMaterial[brushesInOrder.Length];
			var converter = new DirectXBrushConverter(device);
			for(int i = 0; i < materials.Length; i++)
			{
				materials[i] = defaultColor.GetDirectXMaterial();
				if(brushesInOrder[i] == null)
					continue;
				Texture texture;
				materials[i] = converter.TryConvert(brushesInOrder[i], out texture);
				if(texture != null)
					m.Textures[i] = texture;
			}
			return materials;
		}