Exemplo n.º 1
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Before public void setUp()
        public virtual void setUp()
        {
            modelInstance = cloneModelInstance();
            ModelImpl modelImpl = (ModelImpl)modelInstance.Model;

            modelImpl.declareAlternativeNamespace(MECHANICAL_NS, TestModelConstants.NEWER_NAMESPACE);
        }
Exemplo n.º 2
0
        public IModel LoadModel(BmdModelFileBundle modelFileBundle)
        {
            var logger = Logging.Create <BmdModelLoader>();

            var bmd = new BMD(modelFileBundle.BmdFile.Impl.ReadAllBytes());

            List <(string, IBcx)>?pathsAndBcxs;

            try {
                pathsAndBcxs =
                    modelFileBundle
                    .BcxFiles?
                    .Select(bcxFile => {
                    var extension = bcxFile.Extension.ToLower();
                    IBcx bcx      = extension switch {
                        ".bca" =>
                        new BCA(bcxFile.Impl.ReadAllBytes()),
                        ".bck" =>
                        new BCK(bcxFile.Impl.ReadAllBytes()),
                        _ => throw new NotSupportedException(),
                    };
                    return(bcxFile.FullName, bcx);
                })
                    .ToList();
            } catch {
                logger.LogError("Failed to load BCX!");
                throw;
            }

            List <(string, BTI)>?pathsAndBtis;

            try {
                pathsAndBtis =
                    modelFileBundle
                    .BtiFiles?
                    .Select(btiFile
                            => (btiFile.FullName,
                                new BTI(btiFile.Impl.ReadAllBytes())))
                    .ToList();
            } catch {
                logger.LogError("Failed to load BTI!");
                throw;
            }

            var model = new ModelImpl();

            var materialManager =
                new BmdMaterialManager(model, bmd, pathsAndBtis);

            var jointsAndBones = this.ConvertBones_(model, bmd);

            this.ConvertAnimations_(model,
                                    bmd,
                                    pathsAndBcxs,
                                    modelFileBundle.FrameRate,
                                    jointsAndBones);
            this.ConvertMesh_(model, bmd, jointsAndBones, materialManager);

            return(model);
        }
Exemplo n.º 3
0
        public TestRadioModule() : base("/test")
        {
            Get["/"] = _ => {
                return(View["Views/testView"]);
            };

            Post["/"] = parameters => {
                _model = this.Bind <ModelImpl>();
                dynamic data = new ExpandoObject();
                data.Result = _model.Inputs001;
                return(View["Views/result", data]);
            };
        }
Exemplo n.º 4
0
        public IModel LoadModel(DatModelFileBundle modelFileBundle)
        {
            var dat = modelFileBundle.DatFile.Impl.ReadNew <Dat>(Endianness.BigEndian);

            var finModel = new ModelImpl();

            var boneQueue = new Queue <(IBone finParentBone, JObj datBone)>();

            foreach (var datRootBone in dat.RootJObjs)
            {
                boneQueue.Enqueue((finModel.Skeleton.Root, datRootBone));
            }

            while (boneQueue.Count > 0)
            {
                var(finParentBone, datBone) = boneQueue.Dequeue();

                var datBoneData = datBone.Data;

                var finBone =
                    finParentBone.AddChild(datBoneData.Position.X,
                                           datBoneData.Position.Y,
                                           datBoneData.Position.Z)
                    .SetLocalRotationRadians(
                        datBoneData.RotationRadians.X,
                        datBoneData.RotationRadians.Y,
                        datBoneData.RotationRadians.Z)
                    .SetLocalScale(
                        datBoneData.Scale.X,
                        datBoneData.Scale.Y,
                        datBoneData.Scale.Z);

                foreach (var datChildBone in datBone.Children)
                {
                    boneQueue.Enqueue((finBone, datChildBone));
                }
            }

            return(finModel);
        }
Exemplo n.º 5
0
 /// <summary>
 /// 创建ModelElementTypeImpl实例
 /// </summary>
 /// <param name="model">Model实例</param>
 /// <param name="name">ModelElement类型名称</param>
 /// <param name="instanceType">实例Type</param>
 public ModelElementTypeImpl(ModelImpl model, string name, Type instanceType)
 {
     this._model        = model;
     this._typeName     = name;
     this._instanceType = instanceType;
 }
Exemplo n.º 6
0
        private IModel ImportMesh(byte[] bytes)
        {
            int stride = 1;
            MeshNormalExportMode shadingMode = MeshNormalExportMode.Unchanged;

            HWBinaryResourceChunk headerChunk =
                GetFirstChunkOfType(HWBinaryResourceChunkType.XTD_XTDHeader);
            float tileScale =
                BinaryUtils.ReadFloatBigEndian(bytes,
                                               (int)headerChunk.Offset + 12);
            HWBinaryResourceChunk atlasChunk =
                GetFirstChunkOfType(HWBinaryResourceChunkType.XTD_AtlasChunk);

            int gridSize =
                (int)Math.Round(Math.Sqrt((atlasChunk.Size - 32) /
                                          8)); // Subtract the min/range vector sizes, divide by position + normal size, and sqrt for grid size
            int positionOffset = (int)atlasChunk.Offset + 32;
            int normalOffset   = positionOffset + gridSize * gridSize * 4;

            if (gridSize % stride != 0)
            {
                throw new Exception(
                          $"Grid size {gridSize} is not evenly divisible by stride {stride} - choose a different stride value.");
            }

            // These are stored as ZYX, 4 bytes per component
            Vector3 PosCompMin = BinaryUtils
                                 .ReadVector3BigEndian(
                bytes, (int)atlasChunk.Offset)
                                 .ReverseComponents();
            Vector3 PosCompRange =
                BinaryUtils
                .ReadVector3BigEndian(bytes, (int)atlasChunk.Offset + 16)
                .ReverseComponents();

            var finModel = new ModelImpl(gridSize * gridSize);
            var finMesh  = finModel.Skin.AddMesh();

            var finVertices = new IVertex[gridSize * gridSize];

            // Read vertex offsets/normals and add them to the mesh
            for (int x = 0; x < gridSize; x += stride)
            {
                for (int z = 0; z < gridSize; z += stride)
                {
                    int index =
                        ConvertGridPositionToIndex(new Tuple <int, int>(x, z), gridSize);
                    int offset = index * 4;


                    // Get offset position and normal for this vertex
                    Vector3 position =
                        ReadVector3Compressed(bytes, positionOffset + offset) *
                        PosCompRange -
                        PosCompMin;

                    // Positions are relative to the terrain grid, so shift them by the grid position
                    position += new Vector3(x, 0, z) * tileScale;

                    Vector3 normal =
                        ConvertDirectionVector(
                            Vector3.Normalize(
                                ReadVector3Compressed(bytes, normalOffset + offset) *
                                2.0f -
                                Vector3.One));

                    // Simple UV based on original, non-warped terrain grid
                    Vector3 texCoord = new Vector3(x / ((float)gridSize - 1),
                                                   z / ((float)gridSize - 1), 0);

                    var finVertex =
                        finModel.Skin
                        .AddVertex(position.X, position.Y, position.Z)
                        .SetLocalNormal(normal.X, normal.Y, normal.Z)
                        .SetUv(texCoord.X, texCoord.Y);
                    finVertices[GetVertexIndex(x, z, gridSize)] = finVertex;
                }
            }

            // Generate faces based on terrain grid
            for (int x = 0; x < gridSize - stride; x += stride)
            {
                var triangles = new List <(IVertex, IVertex, IVertex)>();

                for (int z = 0; z < gridSize - stride; z += stride)
                {
                    var a = finVertices[GetVertexIndex(x, z, gridSize)];
                    var b = finVertices[GetVertexIndex(x + stride, z, gridSize)];
                    var c = finVertices[GetVertexIndex(x, z + stride, gridSize)];
                    var d = finVertices[GetVertexIndex(x + stride, z + stride, gridSize)];

                    triangles.Add((a, b, c));
                    triangles.Add((d, c, b));
                }

                finMesh.AddTriangles(triangles.ToArray());
                triangles.Clear();
            }

            return(finModel);
        }
Exemplo n.º 7
0
        public unsafe IModel LoadModel(GloModelFileBundle gloModelFileBundle)
        {
            var gloFile            = gloModelFileBundle.GloFile;
            var textureDirectories = gloModelFileBundle.TextureDirectories;
            var fps = 20;

            var glo = gloFile.Impl.ReadNew <Glo>(Endianness.LittleEndian);

            var textureFilesByName = new Dictionary <string, IFileHierarchyFile>();

            foreach (var textureDirectory in textureDirectories)
            {
                foreach (var textureFile in textureDirectory.Files)
                {
                    textureFilesByName[textureFile.Name.ToLower()] = textureFile;
                }
            }

            /*new MeshCsvWriter().WriteToFile(
             *  glo, new FinFile(Path.Join(outputDirectory.FullName, "mesh.csv")));
             * new FaceCsvWriter().WriteToFile(
             *  glo, new FinFile(Path.Join(outputDirectory.FullName, "face.csv")));
             * new VertexCsvWriter().WriteToFile(
             *  glo, new FinFile(Path.Join(outputDirectory.FullName, "vertex.csv")));*/

            var finModel = new ModelImpl();
            var finSkin  = finModel.Skin;

            var finRootBone = finModel.Skeleton.Root;

            var finTextureMap = new LazyDictionary <string, ITexture?>(
                textureFilename => {
                if (!textureFilesByName.TryGetValue(textureFilename.ToLower(),
                                                    out var textureFile))
                {
                    return(null);
                }

                using var rawTextureImage = FinImage.FromFile(textureFile.Impl);
                var textureImageWithAlpha =
                    GloModelLoader.AddTransparencyToGloImage_(rawTextureImage);

                var finTexture = finModel.MaterialManager.CreateTexture(
                    textureImageWithAlpha);
                finTexture.Name = textureFilename;

                if (this.mirrorTextures_.Contains(textureFilename))
                {
                    finTexture.WrapModeU = WrapMode.MIRROR_REPEAT;
                    finTexture.WrapModeV = WrapMode.MIRROR_REPEAT;
                }
                else
                {
                    finTexture.WrapModeU = WrapMode.REPEAT;
                    finTexture.WrapModeV = WrapMode.REPEAT;
                }

                return(finTexture);
            });
            var withCullingMap =
                new LazyDictionary <string, IMaterial>(textureFilename => {
                var finTexture = finTextureMap[textureFilename];
                if (finTexture == null)
                {
                    return(finModel.MaterialManager.AddStandardMaterial());
                }
                return(finModel.MaterialManager.AddTextureMaterial(finTexture));
            });
            var withoutCullingMap = new LazyDictionary <string, IMaterial>(
                textureFilename => {
                var finTexture        = finTextureMap[textureFilename];
                IMaterial finMaterial = finTexture == null
                                        ? finModel.MaterialManager
                                        .AddStandardMaterial()
                                        : finModel.MaterialManager
                                        .AddTextureMaterial(
                    finTexture);
                finMaterial.CullingMode = CullingMode.SHOW_BOTH;
                return(finMaterial);
            });

            var firstMeshMap = new Dictionary <string, GloMesh>();

            // TODO: Consider separating these out as separate models
            foreach (var gloObject in glo.Objects)
            {
                var finObjectRootBone = finRootBone.AddRoot(0, 0, 0);
                var meshQueue         = new Queue <(GloMesh, IBone)>();
                foreach (var topLevelGloMesh in gloObject.Meshes)
                {
                    meshQueue.Enqueue((topLevelGloMesh, finObjectRootBone));
                }

                List <(IAnimation, int, int)> finAndGloAnimations = new();
                foreach (var animSeg in gloObject.AnimSegs)
                {
                    var startFrame = (int)animSeg.StartFrame;
                    var endFrame   = (int)animSeg.EndFrame;

                    var finAnimation = finModel.AnimationManager.AddAnimation();
                    finAnimation.Name       = animSeg.Name;
                    finAnimation.FrameCount =
                        (int)(animSeg.EndFrame - animSeg.StartFrame + 1);

                    finAnimation.FrameRate = fps * animSeg.Speed;

                    finAndGloAnimations.Add((finAnimation, startFrame, endFrame));
                }

                while (meshQueue.Count > 0)
                {
                    var(gloMesh, parentFinBone) = meshQueue.Dequeue();

                    var name = gloMesh.Name;

                    GloMesh idealMesh;
                    if (!firstMeshMap.TryGetValue(name, out idealMesh))
                    {
                        firstMeshMap[name] = idealMesh = gloMesh;
                    }

                    var position = gloMesh.MoveKeys[0].Xyz;

                    var rotation   = gloMesh.RotateKeys[0];
                    var quaternion =
                        new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
                    var xyzRadians = QuaternionUtil.ToEulerRadians(quaternion);

                    var scale = gloMesh.ScaleKeys[0].Scale;

                    var finBone = parentFinBone
                                  .AddChild(position.X, position.Y, position.Z)
                                  .SetLocalRotationRadians(
                        xyzRadians.X, xyzRadians.Y, xyzRadians.Z)
                                  .SetLocalScale(scale.X, scale.Y, scale.Z);
                    finBone.Name = name + "_bone";

                    var child = gloMesh.Pointers.Child;
                    if (child != null)
                    {
                        meshQueue.Enqueue((child, finBone));
                    }

                    var next = gloMesh.Pointers.Next;
                    if (next != null)
                    {
                        meshQueue.Enqueue((next, parentFinBone));
                    }

                    foreach (var(finAnimation, startFrame, endFrame) in
                             finAndGloAnimations)
                    {
                        var finBoneTracks = finAnimation.AddBoneTracks(finBone);

                        long prevTime = -1;
                        foreach (var moveKey in gloMesh.MoveKeys)
                        {
                            Asserts.True(moveKey.Time > prevTime);
                            prevTime = moveKey.Time;

                            if (!(moveKey.Time >= startFrame && moveKey.Time <= endFrame))
                            {
                                continue;
                            }

                            var time = (int)(moveKey.Time - startFrame);
                            Asserts.True(time >= 0 && time < finAnimation.FrameCount);

                            var moveValue = moveKey.Xyz;
                            finBoneTracks.Positions.Set(time, 0, moveValue.X);
                            finBoneTracks.Positions.Set(time, 1, moveValue.Y);
                            finBoneTracks.Positions.Set(time, 2, moveValue.Z);
                        }

                        prevTime = -1;
                        foreach (var rotateKey in gloMesh.RotateKeys)
                        {
                            Asserts.True(rotateKey.Time > prevTime);
                            prevTime = rotateKey.Time;

                            if (!(rotateKey.Time >= startFrame &&
                                  rotateKey.Time <= endFrame))
                            {
                                continue;
                            }

                            var time = (int)(rotateKey.Time - startFrame);
                            Asserts.True(time >= 0 && time < finAnimation.FrameCount);

                            var quaternionKey =
                                new Quaternion(rotateKey.X, rotateKey.Y, rotateKey.Z,
                                               rotateKey.W);
                            var xyzRadiansKey = QuaternionUtil.ToEulerRadians(quaternionKey);

                            finBoneTracks.Rotations.Set(time, 0,
                                                        xyzRadiansKey.X);
                            finBoneTracks.Rotations.Set(time, 1,
                                                        xyzRadiansKey.Y);
                            finBoneTracks.Rotations.Set(time, 2,
                                                        xyzRadiansKey.Z);
                        }

                        prevTime = -1;
                        foreach (var scaleKey in gloMesh.ScaleKeys)
                        {
                            Asserts.True(scaleKey.Time > prevTime);
                            prevTime = scaleKey.Time;

                            if (!(scaleKey.Time >= startFrame && scaleKey.Time <= endFrame))
                            {
                                continue;
                            }

                            var time = (int)(scaleKey.Time - startFrame);
                            Asserts.True(time >= 0 && time < finAnimation.FrameCount);

                            var scaleValue = scaleKey.Scale;
                            finBoneTracks.Scales.Set(time, 0, scaleValue.X);
                            finBoneTracks.Scales.Set(time, 1, scaleValue.Y);
                            finBoneTracks.Scales.Set(time, 2, scaleValue.Z);
                        }
                    }

                    // Anything with these names are debug objects and can be ignored.
                    if (this.hiddenNames_.Contains(name))
                    {
                        continue;
                    }

                    var finMesh = finSkin.AddMesh();
                    finMesh.Name = name;

                    var gloVertices = idealMesh.Vertices;

                    string    previousTextureName = null;
                    IMaterial?previousMaterial    = null;

                    foreach (var gloFace in idealMesh.Faces)
                    {
                        // TODO: What can we do if texture filename is empty?
                        var textureFilename = gloFace.TextureFilename;

                        var gloFaceColor = gloFace.Color;
                        var finFaceColor = ColorImpl.FromRgbaBytes(
                            gloFaceColor.R, gloFaceColor.G, gloFaceColor.B, gloFaceColor.A);

                        var enableBackfaceCulling = (gloFace.Flags & 1 << 2) == 0;

                        IMaterial?finMaterial;
                        if (textureFilename == previousTextureName)
                        {
                            finMaterial = previousMaterial;
                        }
                        else
                        {
                            previousTextureName = textureFilename;
                            finMaterial         = enableBackfaceCulling
                                ? withCullingMap[textureFilename]
                                : withoutCullingMap[textureFilename];
                            previousMaterial = finMaterial;
                        }

                        // Face flag:
                        // 0: potentially some kind of repeat mode??

                        var color = (gloFace.Flags & 1 << 6) != 0
                            ? ColorImpl.FromRgbaBytes(255, 0, 0, 255)
                            : ColorImpl.FromRgbaBytes(0, 255, 0, 255);

                        var finFaceVertices = new IVertex[3];
                        for (var v = 0; v < 3; ++v)
                        {
                            var gloVertexRef = gloFace.VertexRefs[v];
                            var gloVertex    = gloVertices[gloVertexRef.Index];

                            var finVertex = finSkin
                                            .AddVertex(gloVertex.X, gloVertex.Y, gloVertex.Z)
                                            .SetUv(gloVertexRef.U, gloVertexRef.V);
                            //.SetColor(color);
                            finVertex.SetBoneWeights(finSkin.GetOrCreateBoneWeights(
                                                         PreprojectMode.BONE, finBone));
                            finFaceVertices[v] = finVertex;
                        }

                        // TODO: Merge triangles together
                        var finTriangles = new (IVertex, IVertex, IVertex)[1];
Exemplo n.º 8
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @After public void tearDown()
        public virtual void tearDown()
        {
            ModelImpl modelImpl = (ModelImpl)modelInstance.Model;

            modelImpl.undeclareAlternativeNamespace(MECHANICAL_NS);
        }
 public ModelElementTypeBuilderImpl(Type instanceType, string name, ModelImpl model)
 {
     this._instanceType = instanceType;
     this._model        = model;
     _modelType         = new ModelElementTypeImpl(model, name, instanceType);
 }
Exemplo n.º 10
0
 public BpmnModelInstanceImpl(ModelImpl model, ModelBuilder modelBuilder, IDomDocument document)
     : base(model, modelBuilder, document)
 {
 }
Exemplo n.º 11
0
        public IModel LoadModel(OutModelFileBundle modelFileBundle)
        {
            var outFile = modelFileBundle.OutFile;

            var isBw2 = modelFileBundle.GameVersion == GameVersion.BW2;

            Stream stream;

            if (isBw2)
            {
                using var gZipStream =
                          new GZipStream(outFile.Impl.OpenRead(),
                                         CompressionMode.Decompress);

                stream = new MemoryStream();
                gZipStream.CopyTo(stream);
                stream.Position = 0;
            }
            else
            {
                stream = outFile.Impl.OpenRead();
            }

            using var er = new EndianBinaryReader(stream, Endianness.LittleEndian);

            var bwHeightmap =
                isBw2
              ? (IBwHeightmap)er.ReadNew <Bw2Heightmap>()
              : er.ReadNew <Bw1Heightmap>();

            var finModel = new ModelImpl();

            var finSkin = finModel.Skin;
            var finMesh = finSkin.AddMesh();

            var triangles = new List <(IVertex, IVertex, IVertex)>();

            var chunks = bwHeightmap.Chunks;

            var heightmapWidth   = 64 * 4 * 4;
            var heightmapHeight  = 64 * 4 * 4;
            var chunkFinVertices =
                new Grid <IVertex?>(heightmapWidth, heightmapHeight);

            var heights = new Grid <ushort>(heightmapWidth, heightmapHeight);

            for (var chunkY = 0; chunkY < chunks.Height; ++chunkY)
            {
                for (var chunkX = 0; chunkX < chunks.Width; ++chunkX)
                {
                    var tiles = chunks[chunkX, chunkY]?.Tiles;
                    if (tiles == null)
                    {
                        continue;
                    }

                    for (var tileY = 0; tileY < tiles.Height; ++tileY)
                    {
                        for (var tileX = 0; tileX < tiles.Width; ++tileX)
                        {
                            var points = tiles[tileX, tileY].Points;

                            for (var pointY = 0; pointY < points.Height; ++pointY)
                            {
                                for (var pointX = 0; pointX < points.Width; ++pointX)
                                {
                                    var point = points[pointX, pointY];

                                    var heightmapX = 16 * chunkX + 4 * tileX + pointX;
                                    var heightmapY = 16 * chunkY + 4 * tileY + pointY;

                                    var finVertex =
                                        finSkin.AddVertex(point.X, point.Height, point.Y)
                                        .SetUv(1f * heightmapX / heightmapWidth,
                                               1f * heightmapY / heightmapHeight);

                                    chunkFinVertices[heightmapX, heightmapY] = finVertex;
                                    heights[heightmapX, heightmapY]          = point.Height;
                                }
                            }
                        }
                    }
                }
            }

            var image = new I8Image(heightmapWidth, heightmapHeight);

            image.Mutate((_, setHandler) => {
                for (var vY = 0; vY < heightmapHeight; ++vY)
                {
                    for (var vX = 0; vX < heightmapWidth; ++vX)
                    {
                        setHandler(vX, vY, (byte)(heights[vX, vY] / 24));
                    }
                }
            });
            var heightmapTexture = finModel.MaterialManager.CreateTexture(image);
            var finMaterial      =
                finModel.MaterialManager.AddTextureMaterial(heightmapTexture);

            for (var vY = 0; vY < heightmapHeight - 1; ++vY)
            {
                for (var vX = 0; vX < heightmapWidth - 1; ++vX)
                {
                    var a = chunkFinVertices[vX, vY];
                    var b = chunkFinVertices[vX + 1, vY];
                    var c = chunkFinVertices[vX, vY + 1];
                    var d = chunkFinVertices[vX + 1, vY + 1];

                    if (a != null && b != null && c != null && d != null)
                    {
                        triangles.Add((a, b, c));
                        triangles.Add((d, c, b));
                    }
                }
            }

            finMesh.AddTriangles(triangles.ToArray()).SetMaterial(finMaterial);

            return(finModel);
        }
Exemplo n.º 12
0
        // TODO: Split these out into separate classes
        // TODO: Reading from the file here is gross
        public IModel LoadModel(CmbModelFileBundle modelFileBundle)
        {
            var cmbFile   = modelFileBundle.CmbFile;
            var csabFiles = modelFileBundle.CsabFiles;
            var ctxbFiles = modelFileBundle.CtxbFiles;
            var shpaFiles = modelFileBundle.ShpaFiles;

            var fps = 30;

            using var r =
                      new EndianBinaryReader(cmbFile.Impl.OpenRead(),
                                             Endianness.LittleEndian);

            var cmb = new Cmb(r);

            r.Position = 0;

            var filesAndCsabs =
                csabFiles?.Select(csabFile => {
                var csab =
                    csabFile.Impl.ReadNew <Csab>(Endianness.LittleEndian);
                return(csabFile, csab);
            })
                .ToList() ??
                new List <(IFileHierarchyFile shpaFile, Csab csab)>();

            var filesAndCtxbs =
                ctxbFiles?.Select(ctxbFile => {
                var ctxb =
                    ctxbFile.Impl.ReadNew <Ctxb>(Endianness.LittleEndian);
                return(ctxbFile, ctxb);
            })
                .ToList() ??
                new List <(IFileHierarchyFile shpaFile, Ctxb ctxb)>();

            var filesAndShpas =
                shpaFiles?.Select(shpaFile => {
                var shpa =
                    shpaFile.Impl.ReadNew <Shpa>(Endianness.LittleEndian);
                return(shpaFile, shpa);
            })
                .ToList() ??
                new List <(IFileHierarchyFile shpaFile, Shpa shpa)>();

            var finModel = new ModelImpl();
            var finSkin  = finModel.Skin;

            // Adds bones
            var finBones  = new IBone[cmb.skl.bones.Length];
            var boneQueue = new Queue <(Bone, IBone?)>();

            boneQueue.Enqueue((cmb.skl.bones[0], null));
            while (boneQueue.Count > 0)
            {
                var(cmbBone, finBoneParent) = boneQueue.Dequeue();

                var translation = cmbBone.translation;
                var radians     = cmbBone.rotation;
                var scale       = cmbBone.scale;

                var finBone =
                    (finBoneParent ?? finModel.Skeleton.Root)
                    .AddChild(translation.X, translation.Y, translation.Z)
                    .SetLocalRotationRadians(radians.X, radians.Y, radians.Z)
                    .SetLocalScale(scale.X, scale.Y, scale.Z);
                finBones[cmbBone.id] = finBone;

                foreach (var child in cmbBone.children)
                {
                    boneQueue.Enqueue((child, finBone));
                }
            }

            // Adds animations
            foreach (var(csabFile, csab) in filesAndCsabs)
            {
                var finAnimation = finModel.AnimationManager.AddAnimation();
                finAnimation.Name = csabFile.NameWithoutExtension;

                finAnimation.FrameCount = (int)csab.Duration;
                finAnimation.FrameRate  = fps;

                foreach (var(boneIndex, anod) in csab.BoneIndexToAnimationNode)
                {
                    var boneTracks = finAnimation.AddBoneTracks(finBones[boneIndex]);

                    // TODO: Add support for in/out tangents
                    foreach (var translationX in anod.TranslationX.Keyframes)
                    {
                        boneTracks.Positions.Set((int)translationX.Time,
                                                 0,
                                                 translationX.Value,
                                                 translationX.IncomingTangent,
                                                 translationX.OutgoingTangent);
                    }
                    foreach (var translationY in anod.TranslationY.Keyframes)
                    {
                        boneTracks.Positions.Set((int)translationY.Time,
                                                 1,
                                                 translationY.Value,
                                                 translationY.IncomingTangent,
                                                 translationY.OutgoingTangent);
                    }
                    foreach (var translationZ in anod.TranslationZ.Keyframes)
                    {
                        boneTracks.Positions.Set((int)translationZ.Time,
                                                 2,
                                                 translationZ.Value,
                                                 translationZ.IncomingTangent,
                                                 translationZ.OutgoingTangent);
                    }

                    foreach (var scaleX in anod.ScaleX.Keyframes)
                    {
                        boneTracks.Scales.Set((int)scaleX.Time,
                                              0,
                                              scaleX.Value,
                                              scaleX.IncomingTangent,
                                              scaleX.OutgoingTangent);
                    }
                    foreach (var scaleY in anod.ScaleY.Keyframes)
                    {
                        boneTracks.Scales.Set((int)scaleY.Time,
                                              1,
                                              scaleY.Value,
                                              scaleY.IncomingTangent,
                                              scaleY.OutgoingTangent);
                    }
                    foreach (var scaleZ in anod.ScaleZ.Keyframes)
                    {
                        boneTracks.Scales.Set((int)scaleZ.Time,
                                              2,
                                              scaleZ.Value,
                                              scaleZ.IncomingTangent,
                                              scaleZ.OutgoingTangent);
                    }

                    foreach (var rotationX in anod.RotationX.Keyframes)
                    {
                        boneTracks.Rotations.Set((int)rotationX.Time,
                                                 0,
                                                 rotationX.Value,
                                                 rotationX.IncomingTangent,
                                                 rotationX.OutgoingTangent);
                    }
                    foreach (var rotationY in anod.RotationY.Keyframes)
                    {
                        boneTracks.Rotations.Set((int)rotationY.Time,
                                                 1,
                                                 rotationY.Value,
                                                 rotationY.IncomingTangent,
                                                 rotationY.OutgoingTangent);
                    }
                    foreach (var rotationZ in anod.RotationZ.Keyframes)
                    {
                        boneTracks.Rotations.Set((int)rotationZ.Time,
                                                 2,
                                                 rotationZ.Value,
                                                 rotationZ.IncomingTangent,
                                                 rotationZ.OutgoingTangent);
                    }
                }
            }

            // TODO: Move these reads into the model reading logic
            var ctrTexture    = new CtrTexture();
            var textureImages =
                cmb.tex.textures.Select(cmbTexture => {
                var position = cmb.startOffset +
                               cmb.header.textureDataOffset +
                               cmbTexture.dataOffset;
                IImage image;
                if (position != 0)
                {
                    r.Position = position;
                    var data   =
                        r.ReadBytes((int)cmbTexture.dataLength);
                    image =
                        ctrTexture.DecodeImage(data, cmbTexture);
                }
                else
                {
                    var ctxb =
                        filesAndCtxbs
                        .Select(
                            fileAndCtxb => fileAndCtxb.Item2)
                        .Single(ctxb => ctxb.Chunk.Entry.name == cmbTexture.name);
                    image =
                        ctrTexture.DecodeImage(ctxb.Data,
                                               cmbTexture);
                }
                return(image);
            })
                .ToArray();

            // Creates meshes & textures
            // TODO: Emulate fixed-function materials
            var finMaterials = new List <IMaterial>();

            for (var i = 0; i < cmb.mat.materials.Length; ++i)
            {
                var cmbMaterial = cmb.mat.materials[i];

                // Get associated texture
                var texMapper = cmbMaterial.texMappers[0];
                var textureId = texMapper.textureId;

                ITexture?finTexture = null;
                if (textureId != -1)
                {
                    var cmbTexture   = cmb.tex.textures[textureId];
                    var textureImage = textureImages[textureId];

                    finTexture           = finModel.MaterialManager.CreateTexture(textureImage);
                    finTexture.Name      = cmbTexture.name;
                    finTexture.WrapModeU = this.CmbToFinWrapMode(texMapper.wrapS);
                    finTexture.WrapModeV = this.CmbToFinWrapMode(texMapper.wrapT);
                }

                // Create material
                IMaterial finMaterial = finTexture != null
                                    ? finModel.MaterialManager
                                        .AddTextureMaterial(
                    finTexture)
                                    : finModel.MaterialManager
                                        .AddLayerMaterial();

                finMaterial.Name        = $"material{i}";
                finMaterial.CullingMode = cmbMaterial.faceCulling switch {
                    CullMode.FrontAndBack => CullingMode.SHOW_BOTH,
                    CullMode.Front => CullingMode.SHOW_FRONT_ONLY,
                    CullMode.BackFace => CullingMode.SHOW_BACK_ONLY,
                    CullMode.Never => CullingMode.SHOW_NEITHER,
                    _ => throw new NotImplementedException(),
                };

                finMaterials.Add(finMaterial);
            }

            /*{
             * var nameToTextures = new Dictionary<string, ITexture>();
             * foreach (var finMaterial in finMaterials) {
             *  foreach (var finTexture in finMaterial.Textures) {
             *    nameToTextures[finTexture.Name] = finTexture;
             *  }
             * }
             *
             * foreach (var (_, finTexture) in nameToTextures) {
             *  finTexture.ImageData.Save(
             *      Path.Join(outputDirectory.FullName, finTexture.Name + ".png"));
             * }
             * }*/

            var verticesByIndex = new ListDictionary <int, IVertex>();

            // Adds meshes
            foreach (var cmbMesh in cmb.sklm.meshes.meshes)
            {
                var shape = cmb.sklm.shapes.shapes[cmbMesh.shapeIndex];

                uint vertexCount = 0;
                var  meshIndices = new List <uint>();
                foreach (var pset in shape.primitiveSets)
                {
                    foreach (var index in pset.primitive.indices)
                    {
                        meshIndices.Add(index);
                        vertexCount = Math.Max(vertexCount, index);
                    }
                }
                ++vertexCount;

                var preproject    = new bool?[vertexCount];
                var skinningModes = new SkinningMode?[vertexCount];
                foreach (var pset in shape.primitiveSets)
                {
                    foreach (var index in pset.primitive.indices)
                    {
                        skinningModes[index] = pset.skinningMode;
                        preproject[index]    = pset.skinningMode != SkinningMode.Smooth;
                    }
                }

                // Gets flags
                var inc    = 1;
                var hasNrm = BitLogic.GetFlag(shape.vertFlags, inc++);
                if (cmb.header.version > CmbVersion.OCARINA_OF_TIME_3D)
                {
                    // Skip "HasTangents" for now
                    inc++;
                }
                var hasClr = BitLogic.GetFlag(shape.vertFlags, inc++);
                var hasUv0 = BitLogic.GetFlag(shape.vertFlags, inc++);
                var hasUv1 = BitLogic.GetFlag(shape.vertFlags, inc++);
                var hasUv2 = BitLogic.GetFlag(shape.vertFlags, inc++);
                var hasBi  = BitLogic.GetFlag(shape.vertFlags, inc++);
                var hasBw  = BitLogic.GetFlag(shape.vertFlags, inc++);

                // Gets bone indices
                var boneCount = shape.boneDimensions;
                var bIndices  = new short[vertexCount * boneCount];
                foreach (var pset in shape.primitiveSets)
                {
                    foreach (var i in pset.primitive.indices)
                    {
                        if (hasBi && pset.skinningMode != SkinningMode.Single)
                        {
                            r.Position = cmb.startOffset +
                                         cmb.header.vatrOffset +
                                         cmb.vatr.bIndices.StartOffset +
                                         shape.bIndices.Start +
                                         i *
                                         DataTypeUtil.GetSize(shape.bIndices.DataType) *
                                         shape.boneDimensions;
                            for (var bi = 0; bi < shape.boneDimensions; ++bi)
                            {
                                var boneTableIndex = shape.bIndices.Scale *
                                                     DataTypeUtil.Read(
                                    r,
                                    shape.bIndices.DataType);
                                bIndices[i * boneCount + bi] =
                                    pset.boneTable[(int)boneTableIndex];
                            }
                        }
                        else
                        {
                            bIndices[i] = shape.primitiveSets[0].boneTable[0];
                        }
                    }
                }

                var finMesh = finSkin.AddMesh();

                // TODO: Encapsulate these reads somewhere else
                // Get vertices
                var finVertices = new IVertex[vertexCount];
                for (var i = 0; i < vertexCount; ++i)
                {
                    // Position
                    r.Position = cmb.startOffset +
                                 cmb.header.vatrOffset +
                                 cmb.vatr.position.StartOffset +
                                 shape.position.Start +
                                 3 * DataTypeUtil.GetSize(shape.position.DataType) * i;
                    var positionValues =
                        DataTypeUtil.Read(r, 3, shape.position.DataType)
                        .Select(value => value * shape.position.Scale)
                        .ToArray();

                    var finVertex = finSkin.AddVertex(positionValues[0],
                                                      positionValues[1],
                                                      positionValues[2]);
                    finVertices[i] = finVertex;

                    var index = (ushort)(shape.position.Start / 3 + i);
                    verticesByIndex.Add(index, finVertex);

                    if (hasNrm)
                    {
                        r.Position = cmb.startOffset +
                                     cmb.header.vatrOffset +
                                     cmb.vatr.normal.StartOffset +
                                     shape.normal.Start +
                                     3 * DataTypeUtil.GetSize(shape.normal.DataType) * i;
                        var normalValues =
                            DataTypeUtil.Read(r, 3, shape.normal.DataType)
                            .Select(value => value * shape.normal.Scale)
                            .ToArray();
                        finVertex.SetLocalNormal(normalValues[0],
                                                 normalValues[1],
                                                 normalValues[2]);
                    }

                    if (hasClr)
                    {
                        r.Position = cmb.startOffset +
                                     cmb.header.vatrOffset +
                                     cmb.vatr.color.StartOffset +
                                     shape.color.Start +
                                     4 * DataTypeUtil.GetSize(shape.color.DataType) * i;
                        var colorValues =
                            DataTypeUtil.Read(r, 4, shape.color.DataType)
                            .Select(value => value * shape.color.Scale)
                            .ToArray();

                        finVertex.SetColorBytes((byte)(colorValues[0] * 255),
                                                (byte)(colorValues[1] * 255),
                                                (byte)(colorValues[2] * 255),
                                                (byte)(colorValues[3] * 255));
                    }

                    if (hasUv0)
                    {
                        r.Position = cmb.startOffset +
                                     cmb.header.vatrOffset +
                                     cmb.vatr.uv0.StartOffset +
                                     shape.uv0.Start +
                                     2 * DataTypeUtil.GetSize(shape.uv0.DataType) * i;
                        var uv0Values =
                            DataTypeUtil.Read(r, 2, shape.uv0.DataType)
                            .Select(value => value * shape.uv0.Scale)
                            .ToArray();

                        finVertex.SetUv(0, uv0Values[0], 1 - uv0Values[1]);
                    }
                    if (hasUv1)
                    {
                        r.Position = cmb.startOffset +
                                     cmb.header.vatrOffset +
                                     cmb.vatr.uv1.StartOffset +
                                     shape.uv1.Start +
                                     2 * DataTypeUtil.GetSize(shape.uv1.DataType) * i;
                        var uv1Values =
                            DataTypeUtil.Read(r, 2, shape.uv1.DataType)
                            .Select(value => value * shape.uv1.Scale)
                            .ToArray();

                        finVertex.SetUv(1, uv1Values[0], 1 - uv1Values[1]);
                    }
                    if (hasUv2)
                    {
                        r.Position = cmb.startOffset +
                                     cmb.header.vatrOffset +
                                     cmb.vatr.uv2.StartOffset +
                                     shape.uv2.Start +
                                     2 * DataTypeUtil.GetSize(shape.uv2.DataType) * i;
                        var uv2Values =
                            DataTypeUtil.Read(r, 2, shape.uv2.DataType)
                            .Select(value => value * shape.uv2.Scale)
                            .ToArray();

                        finVertex.SetUv(2, uv2Values[0], 1 - uv2Values[1]);
                    }

                    var preprojectMode = preproject[i].Value
                                   ? PreprojectMode.BONE
                                   : PreprojectMode.NONE;

                    if (hasBw)
                    {
                        r.Position = cmb.startOffset +
                                     cmb.header.vatrOffset +
                                     cmb.vatr.bWeights.StartOffset +
                                     shape.bWeights.Start +
                                     i *
                                     DataTypeUtil.GetSize(shape.bWeights.DataType) *
                                     boneCount;

                        var totalWeight = 0f;
                        var boneWeights = new List <BoneWeight>();
                        for (var j = 0; j < boneCount; ++j)
                        {
                            // TODO: Looks like this is rounded to the nearest 2 in the original??
                            var weight = DataTypeUtil.Read(r, shape.bWeights.DataType) *
                                         shape.bWeights.Scale;
                            totalWeight += weight;

                            if (weight > 0)
                            {
                                var bone =
                                    finBones[bIndices[i * boneCount + j]];
                                var boneWeight = new BoneWeight(bone, null, weight);

                                boneWeights.Add(boneWeight);
                            }
                        }

                        Asserts.True(boneWeights.Count > 0);
                        Asserts.True(Math.Abs(1 - totalWeight) < .0001);
                        finVertex.SetBoneWeights(
                            finSkin.GetOrCreateBoneWeights(preprojectMode,
                                                           boneWeights.ToArray()));
                    }
                    else
                    {
                        var boneIndex = bIndices[i];
                        finVertex.SetBoneWeights(
                            finSkin.GetOrCreateBoneWeights(preprojectMode,
                                                           finBones[boneIndex]));
                    }

                    finVertex.SetColor(ColorImpl.FromSystemColor(Color.White));
                }

                // Adds faces. Thankfully, it's all just triangles!
                var triangleVertices = meshIndices
                                       .Select(meshIndex => finVertices[meshIndex])
                                       .ToArray();
                finMesh.AddTriangles(triangleVertices)
                .SetMaterial(finMaterials[cmbMesh.materialIndex])
                .SetVertexOrder(VertexOrder.NORMAL);
            }

            // Adds morph targets
            foreach (var(shpaFile, shpa) in filesAndShpas)
            {
                var shpaIndexToPosi =
                    shpa?.Posi.Values.Select((posi, i) => (shpa.Idxs.Indices[i], posi))
                    .ToDictionary(indexAndPosi => indexAndPosi.Item1,
                                  indexAndPosi => indexAndPosi.posi);

                var morphTarget = finModel.AnimationManager.AddMorphTarget();
                morphTarget.Name = shpaFile.NameWithoutExtension;

                foreach (var(index, position) in shpaIndexToPosi)
                {
                    if (!verticesByIndex.TryGetList(index, out var finVertices))
                    {
                        continue;
                    }

                    foreach (var finVertex in finVertices)
                    {
                        morphTarget.MoveTo(finVertex, position);
                    }
                }
            }

            return(finModel);
        }
Exemplo n.º 13
0
        public IModel LoadModel(ModlModelFileBundle modelFileBundle)
        {
            var flipSign = ModlFlags.FLIP_HORIZONTALLY ? -1 : 1;

            var modlFile = modelFileBundle.ModlFile;

            using var er = new EndianBinaryReader(modlFile.Impl.OpenRead(),
                                                  Endianness.LittleEndian);
            var bwModel = modelFileBundle.ModlType switch {
                ModlType.BW1 => (IModl)er.ReadNew <Bw1Modl>(),
                ModlType.BW2 => er.ReadNew <Bw2Modl>(),
            };

            var model   = new ModelImpl();
            var finMesh = model.Skin.AddMesh();

            var finBones             = new IBone[bwModel.Nodes.Count];
            var finBonesByModlNode   = new Dictionary <IBwNode, IBone>();
            var finBonesByIdentifier = new Dictionary <string, IBone>();

            {
                var nodeQueue =
                    new FinTuple2Queue <IBone, ushort>((model.Skeleton.Root, 0));

                while (nodeQueue.TryDequeue(out var parentFinBone,
                                            out var modlNodeId))
                {
                    var modlNode = bwModel.Nodes[modlNodeId];

                    var transform    = modlNode.Transform;
                    var bonePosition = transform.Position;

                    var modlRotation = transform.Rotation;
                    var rotation     = new Quaternion(
                        flipSign * modlRotation.X,
                        modlRotation.Y,
                        modlRotation.Z,
                        flipSign * modlRotation.W);
                    var eulerRadians = QuaternionUtil.ToEulerRadians(rotation);

                    var finBone =
                        parentFinBone
                        .AddChild(flipSign * bonePosition.X, bonePosition.Y,
                                  bonePosition.Z)
                        .SetLocalRotationRadians(
                            eulerRadians.X, eulerRadians.Y, eulerRadians.Z);

                    var identifier = modlNode.GetIdentifier();
                    finBone.Name                     = identifier;
                    finBones[modlNodeId]             = finBone;
                    finBonesByModlNode[modlNode]     = finBone;
                    finBonesByIdentifier[identifier] = finBone;

                    if (bwModel.CnctParentToChildren.TryGetList(
                            modlNodeId, out var modlChildIds))
                    {
                        nodeQueue.Enqueue(
                            modlChildIds !.Select(modlChildId => (finBone, modlChildId)));
                    }
                }

                foreach (var animFile in modelFileBundle.AnimFiles ??
                         Array.Empty <IFileHierarchyFile>())
                {
                    var anim = modelFileBundle.ModlType switch {
                        ModlType.BW1 => (IAnim)animFile.Impl.ReadNew <Bw1Anim>(
                            Endianness.BigEndian),
                        ModlType.BW2 => animFile.Impl.ReadNew <Bw2Anim>(
                            Endianness.BigEndian)
                    };

                    var maxFrameCount = -1;
                    foreach (var animBone in anim.AnimBones)
                    {
                        maxFrameCount = (int)Math.Max(maxFrameCount,
                                                      Math.Max(
                                                          animBone
                                                          .PositionKeyframeCount,
                                                          animBone
                                                          .RotationKeyframeCount));
                    }

                    var finAnimation = model.AnimationManager.AddAnimation();
                    finAnimation.Name       = animFile.NameWithoutExtension;
                    finAnimation.FrameRate  = 30;
                    finAnimation.FrameCount = maxFrameCount;

                    for (var b = 0; b < anim.AnimBones.Count; ++b)
                    {
                        var animBone       = anim.AnimBones[b];
                        var animBoneFrames = anim.AnimBoneFrames[b];

                        var animNodeIdentifier = animBone.GetIdentifier();
                        if (!finBonesByIdentifier.TryGetValue(
                                animNodeIdentifier, out var finBone))
                        {
                            // TODO: Gross hack for the vet models, what's the real fix???
                            if (animNodeIdentifier == Bw1Node.GetIdentifier(33))
                            {
                                finBone = finBonesByIdentifier[Bw1Node.GetIdentifier(34)];
                            }
                            else if (finBonesByIdentifier.TryGetValue(
                                         animNodeIdentifier + 'X', out var xBone))
                            {
                                finBone = xBone;
                            }
                            else if (finBonesByIdentifier.TryGetValue(
                                         "BONE_" + animNodeIdentifier,
                                         out var prefixBone))
                            {
                                finBone = prefixBone;
                            }
                            else if (animNodeIdentifier == "WF_GRUNT_BACKPAC")
                            {
                                // TODO: Is this right?????
                                finBone = finBonesByIdentifier["BONE_BCK_MISC"];
                            }
                            else
                            {
                                ;
                            }
                        }

                        var finBoneTracks = finAnimation.AddBoneTracks(finBone !);

                        var fbtPositions = finBoneTracks.Positions;
                        for (var f = 0; f < animBone.PositionKeyframeCount; ++f)
                        {
                            var(fPX, fPY, fPZ) = animBoneFrames.PositionFrames[f];

                            fbtPositions.Set(f, 0, flipSign * fPX);
                            fbtPositions.Set(f, 1, fPY);
                            fbtPositions.Set(f, 2, fPZ);
                        }

                        var fbtRotations = finBoneTracks.Rotations;
                        for (var f = 0; f < animBone.RotationKeyframeCount; ++f)
                        {
                            var(fRX, fRY, fRZ, frW) = animBoneFrames.RotationFrames[f];

                            var animationQuaternion =
                                new Quaternion(flipSign * fRX, fRY, fRZ, flipSign * frW);
                            var eulerRadians =
                                QuaternionUtil.ToEulerRadians(animationQuaternion);

                            fbtRotations.Set(f, 0, eulerRadians.X);
                            fbtRotations.Set(f, 1, eulerRadians.Y);
                            fbtRotations.Set(f, 2, eulerRadians.Z);
                        }
                    }
                }

                var textureDictionary = new LazyDictionary <string, ITexture>(
                    textureName => {
                    var textureFile =
                        modlFile.Parent.Files.Single(
                            file => file.Name.ToLower() == $"{textureName}.png");

                    var image = FinImage.FromFile(textureFile.Impl);

                    var finTexture =
                        model.MaterialManager.CreateTexture(image);
                    finTexture.Name = textureName;

                    // TODO: Need to handle wrapping
                    finTexture.WrapModeU = WrapMode.REPEAT;
                    finTexture.WrapModeV = WrapMode.REPEAT;

                    return(finTexture);
                });

                foreach (var modlNode in bwModel.Nodes)
                {
                    var finMaterials =
                        modlNode.Materials.Select(modlMaterial => {
                        var textureName = modlMaterial.Texture1.ToLower();
                        if (textureName == "")
                        {
                            return(null);
                        }

                        var finTexture = textureDictionary[textureName];

                        var finMaterial =
                            model.MaterialManager
                            .AddTextureMaterial(finTexture);

                        return(finMaterial);
                    })
                        .ToArray();

                    foreach (var modlMesh in modlNode.Meshes)
                    {
                        var finMaterial = finMaterials[modlMesh.MaterialIndex];

                        foreach (var triangleStrip in modlMesh.TriangleStrips)
                        {
                            var vertices =
                                new IVertex[triangleStrip.VertexAttributeIndicesList.Count];
                            for (var i = 0; i < vertices.Length; i++)
                            {
                                var vertexAttributeIndices =
                                    triangleStrip.VertexAttributeIndicesList[i];

                                var position =
                                    modlNode.Positions[vertexAttributeIndices.PositionIndex];
                                var vertex = vertices[i] = model.Skin.AddVertex(
                                    flipSign * position.X * modlNode.Scale,
                                    position.Y * modlNode.Scale,
                                    position.Z * modlNode.Scale);

                                if (vertexAttributeIndices.NormalIndex != null)
                                {
                                    var normal =
                                        modlNode.Normals[
                                            vertexAttributeIndices.NormalIndex.Value];
                                    vertex.SetLocalNormal(flipSign * normal.X, normal.Y,
                                                          normal.Z);
                                }

                                if (vertexAttributeIndices.NodeIndex != null)
                                {
                                    var finBone =
                                        finBones[vertexAttributeIndices.NodeIndex.Value];
                                    vertex.SetBoneWeights(
                                        model.Skin
                                        .GetOrCreateBoneWeights(
                                            PreprojectMode.NONE,
                                            new BoneWeight(finBone, null, 1)));
                                }
                                else
                                {
                                    var finBone = finBonesByModlNode[modlNode];
                                    vertex.SetBoneWeights(
                                        model.Skin.GetOrCreateBoneWeights(
                                            PreprojectMode.BONE, finBone));
                                }

                                var texCoordIndex0 = vertexAttributeIndices.TexCoordIndices[0];
                                var texCoordIndex1 = vertexAttributeIndices.TexCoordIndices[1];
                                if (texCoordIndex1 != null)
                                {
                                    int texCoordIndex;
                                    if (texCoordIndex0 != null)
                                    {
                                        texCoordIndex =
                                            (texCoordIndex0.Value << 8) | texCoordIndex1.Value;
                                    }
                                    else
                                    {
                                        texCoordIndex = texCoordIndex1.Value;
                                    }

                                    var uv = modlNode.UvMaps[0][texCoordIndex];
                                    vertex.SetUv(uv.U, uv.V);
                                }
                            }

                            var triangleStripPrimitive = finMesh.AddTriangleStrip(vertices);
                            if (finMaterial != null)
                            {
                                triangleStripPrimitive.SetMaterial(finMaterial);
                            }
                        }
                    }
                }
            }

            return(model);
        }
    }
Exemplo n.º 14
0
 //TODO Attribute Id,Name等解析
 public DmnModelInstanceImpl(ModelImpl model, ModelBuilder modelBuilder, IDomDocument document) : base(model, modelBuilder, document)
 {
     //var test = Definitions;
 }