示例#1
0
 public SurPart ToSurHierarchy(out Dictionary <Part, SurPart> surParts)
 {
     surParts = new Dictionary <Part, SurPart>();
     foreach (var part in Parts)
     {
         var sp = new SurPart()
         {
             Children = new List <SurPart>(), Hash = CrcTool.FLModelCrc(part.ObjectName)
         };
         surParts.Add(part, sp);
     }
     foreach (var part in Parts)
     {
         if (part.Construct != null)
         {
             var p = Parts.FirstOrDefault((x) =>
                                          x.ObjectName.Equals(part.Construct.ParentName, StringComparison.OrdinalIgnoreCase));
             if (p != null)
             {
                 surParts[p].Children.Add(surParts[part]);
             }
         }
     }
     return(surParts[GetRootPart()]);
 }
示例#2
0
        public byte[] VMeshRef(string nodename)
        {
            using (var stream = new MemoryStream())
            {
                var writer = new BinaryWriter(stream);

                writer.Write((uint)60); //HeaderSize
                writer.Write(CrcTool.FLModelCrc(nodename));
                //Fields used for referencing sections of VMeshData
                writer.Write((ushort)0);                //StartVertex - BaseVertex in drawcall
                writer.Write((ushort)Vertices.Length);  //VertexCount (idk?)
                writer.Write((ushort)0);                //StartIndex
                writer.Write((ushort)Indices.Length);   //IndexCount
                writer.Write((ushort)0);                //StartMesh
                writer.Write((ushort)Drawcalls.Length); //MeshCount
                //Write rendering things
                writer.Write(Max.X);
                writer.Write(Min.X);
                writer.Write(Max.Y);
                writer.Write(Min.Y);
                writer.Write(Max.Z);
                writer.Write(Min.Z);


                writer.Write(Center.X);
                writer.Write(Center.Y);
                writer.Write(Center.Z);

                writer.Write(Radius);
                return(stream.ToArray());
            }
        }
示例#3
0
        public void Test1()
        {
            var buffer = new byte[] { 0x00, 0x1E, 0x01, 0x1A, 0x00, 0x00, 0x01, 0x01 };

            var actual = CrcTool.CaculateCCITT16(buffer, 0, buffer.Length);

            Assert.AreEqual(0x1089, actual);
        }
 void ProcessSur(LibreLancer.Physics.Sur.SurFile surfile)
 {
     if (surs != null)
     {
         foreach (var mdl in surs)
         {
             mdl.Vertices.Dispose();
             mdl.Elements.Dispose();
         }
     }
     surs = new List <SurModel>();
     if ((drawable is ModelFile))
     {
         surs.Add(GetSurModel(surfile.GetMesh(0, false), null, surPart));
         foreach (var hpid in surfile.HardpointIds)
         {
             surs.Add(GetSurModel(surfile.GetMesh(hpid, true), null, surHardpoint));
         }
     }
     else
     {
         Dictionary <Part, SurPart> surParts;
         var surHierarchy = ((CmpFile)drawable).ToSurHierarchy(out surParts);
         surfile.FillMeshHierarchy(surHierarchy);
         foreach (var kv in surParts)
         {
             var mdl = new SurModel()
             {
                 Part = kv.Key
             };
             foreach (var hp in kv.Key.Model.Hardpoints)
             {
                 var crc = CrcTool.FLModelCrc(hp.Name);
                 if (surfile.HardpointIds.Contains(crc))
                 {
                     surs.Add(GetSurModel(surfile.GetMesh(crc, true), kv.Key, surHardpoint));
                 }
             }
             if (kv.Value.DisplayMeshes != null)
             {
                 foreach (var msh in kv.Value.DisplayMeshes)
                 {
                     AddVertices(mdl, msh);
                 }
             }
             mdl.Vertices = new VertexBuffer(typeof(VertexPositionColor), mdl.BuildVertices.Count);
             mdl.Vertices.SetData(mdl.BuildVertices.ToArray());
             mdl.BuildVertices = null;
             mdl.Elements      = new ElementBuffer(mdl.BuildIndices.Count);
             mdl.Elements.SetData(mdl.BuildIndices.ToArray());
             mdl.Vertices.SetElementBuffer(mdl.Elements);
             mdl.BuildIndices = null;
             surs.Add(mdl);
         }
     }
 }
示例#5
0
        public RigidModel CreateRigidModel(bool drawable)
        {
            var model = new RigidModel();
            var part  = new RigidModelPart();
            var dcs   = new List <MeshDrawcall>();
            var scale = Matrix4x4.CreateScale(Radius);

            if (drawable && SideMaterials.Length >= 6)
            {
                for (int i = 0; i < 6; i++)
                {
                    int     start, count;
                    Vector3 pos;
                    sphere.GetDrawParameters(faces[i], out start, out count, out pos);
                    var dc = new MeshDrawcall();
                    dc.Buffer         = sphere.VertexBuffer;
                    dc.MaterialCrc    = CrcTool.FLModelCrc(sideMaterialNames[i]);
                    dc.BaseVertex     = 0;
                    dc.StartIndex     = start;
                    dc.PrimitiveCount = count;
                    dc.HasScale       = true;
                    dc.Scale          = scale;
                    dcs.Add(dc);
                }

                if (SideMaterials.Length > 6)
                {
                    var crc = CrcTool.FLModelCrc(sideMaterialNames[6]);
                    for (int i = 0; i < 6; i++)
                    {
                        int     start, count;
                        Vector3 pos;
                        sphere.GetDrawParameters(faces[i], out start, out count, out pos);
                        var dc = new MeshDrawcall();
                        dc.Buffer         = sphere.VertexBuffer;
                        dc.MaterialCrc    = crc;
                        dc.BaseVertex     = 0;
                        dc.StartIndex     = start;
                        dc.PrimitiveCount = count;
                        dc.HasScale       = true;
                        dc.Scale          = scale;
                        dcs.Add(dc);
                    }
                }
            }
            var vmesh = new VisualMesh();

            vmesh.Radius      = Radius;
            vmesh.BoundingBox = BoundingBox.CreateFromSphere(new BoundingSphere(Vector3.Zero, Radius));
            vmesh.Levels      = new[] { dcs.ToArray() };
            part.Hardpoints   = new List <Hardpoint>();
            part.Mesh         = vmesh;
            model.Root        = part;
            model.AllParts    = new[] { part };
            return(model);
        }
示例#6
0
 void CheckNullArray()
 {
     if (sph.sideMaterials == null)
     {
         sph.sideMaterials = new Material[sph.sideMaterialNames.Count];
         for (int i = 0; i < sph.sideMaterialNames.Count; i++)
         {
             sph.sideMaterials[i] = sph.library.FindMaterial(CrcTool.FLModelCrc(sph.sideMaterialNames[i]));
         }
     }
 }
示例#7
0
 private void setMeshes(IntermediateNode vMeshLibrary, ILibFile materialLibrary)
 {
     foreach (IntermediateNode vmsNode in vMeshLibrary)
     {
         if (vmsNode.Count != 1)
         {
             throw new Exception("Invalid VMeshLibrary: More than one child or zero elements: " + vmsNode.Name);
         }
         LeafNode vMeshDataNode = vmsNode[0] as LeafNode;
         Meshes.Add(CrcTool.FLModelCrc(vmsNode.Name), new VMeshData(vMeshDataNode.ByteArrayData, materialLibrary, vmsNode.Name));
     }
 }
示例#8
0
        /// <summary>
        /// 解析指定的字节流。
        /// </summary>
        public void ParseBytes(byte[] bytes)
        {
            if (bytes == null || bytes.Length < AleFrame.HeadLength)
            {
                throw new AleFrameParsingException("无法将指定的字节流解析为AleFrame,长度不够。");
            }

            int startIndex = 0;

            // 包长度
            var pktLen = RsspEncoding.ToHostUInt16(bytes, startIndex);

            startIndex += AleFrame.SizeofHeadLen;

            // 版本
            this.Version = bytes[startIndex++];

            // 应用类型
            this.ApplicationType = bytes[startIndex++];

            // 传输序列号
            this.SequenceNo = RsspEncoding.ToHostUInt16(bytes, startIndex);
            startIndex     += 2;

            // N/R标志
            this.IsNormal = (bytes[startIndex++] == 1);

            // 包类型
            this.FrameType = (AleFrameType)bytes[startIndex++];

            // 校验和
            if (this.FrameType != AleFrameType.KAA && this.FrameType != AleFrameType.KANA) // 生命信息不需要校验
            {
                //var actualCrcValue = BitConverter.ToUInt16(bytes, startIndex);
                var actualCrcValue   = RsspEncoding.ToHostUInt16(bytes, startIndex);
                var expectedCrcValue = CrcTool.CaculateCCITT16(bytes, 0, 8);
                if (actualCrcValue != expectedCrcValue)
                {
                    throw new AleFrameParsingException(string.Format("解析Ale协议帧时发生异常,CRC检验不一致,期望值是{0},实际值是{1}。",
                                                                     expectedCrcValue, actualCrcValue));
                }
            }
            startIndex += 2;

            // 用户数据
            var userDataLen = pktLen - (AleFrame.HeadLength - AleFrame.SizeofHeadLen);

            if (userDataLen < 0)
            {
                throw new AleFrameParsingException(string.Format("将字节流解析为ALE帧时发生异常,用户数据长度为负值{0}。", userDataLen));
            }
            this.UserData = AleUserData.Parse(this.FrameType, bytes, startIndex, startIndex + userDataLen - 1);
        }
示例#9
0
        /// <summary>
        /// 获取序列化后的字节流。
        /// </summary>
        public byte[] GetBytes()
        {
            var bytes      = new byte[AleFrame.HeadLength + this.UserDataLength];
            var startIndex = 0;

            // 包长度
            var tempBuf = RsspEncoding.ToNetUInt16(this.PacketLength);

            Array.Copy(tempBuf, 0, bytes, startIndex, tempBuf.Length);
            startIndex += AleFrame.SizeofHeadLen;

            // 版本
            bytes[startIndex++] = this.Version;

            // 应用类型
            bytes[startIndex++] = this.ApplicationType;

            // 传输序列号
            tempBuf = RsspEncoding.ToNetUInt16(this.SequenceNo);
            Array.Copy(tempBuf, 0, bytes, startIndex, tempBuf.Length);
            startIndex += 2;

            // N/R标志
            bytes[startIndex++] = (byte)(this.IsNormal ? 1 : 0);

            // 包类型
            bytes[startIndex++] = (byte)this.FrameType;

            // 校验和
            var crcValue = CrcTool.CaculateCCITT16(bytes, 0, 8);

            //tempBuf = BitConverter.GetBytes(crcValue);
            tempBuf = RsspEncoding.ToNetUInt16(crcValue);
            Array.Copy(tempBuf, 0, bytes, startIndex, tempBuf.Length);
            startIndex += 2;

            // 用户数据
            var userData = this.UserData.GetBytes();

            if (userData != null)
            {
                Array.Copy(userData, 0, bytes, startIndex, this.UserDataLength);
            }

            return(bytes);
        }
示例#10
0
 public ALEffectLib(LeafNode node)
 {
     using (var reader = new BinaryReader(new MemoryStream(node.ByteArrayData))) {
         Version = reader.ReadSingle();
         var effectCount = reader.ReadInt32();
         Effects = new List <ALEffect> (effectCount);
         for (int ef = 0; ef < effectCount; ef++)
         {
             ushort nameLen = reader.ReadUInt16();
             var    name    = Encoding.ASCII.GetString(reader.ReadBytes(nameLen)).TrimEnd('\0');
             reader.BaseStream.Seek((nameLen & 1), SeekOrigin.Current);
             if (Version == 1.1f)
             {
                 //Skip 4 unused floats
                 reader.BaseStream.Seek(4 * sizeof(float), SeekOrigin.Current);
             }
             int fxCount = reader.ReadInt32();
             var refs    = new List <AlchemyNodeRef> (fxCount);
             for (int i = 0; i < fxCount; i++)
             {
                 refs.Add(new AlchemyNodeRef(
                              reader.ReadUInt32(),
                              reader.ReadUInt32(),
                              reader.ReadUInt32(),
                              reader.ReadUInt32()
                              ));
             }
             int pairsCount = reader.ReadInt32();
             var pairs      = new List <Tuple <uint, uint> > (pairsCount);
             for (int i = 0; i < pairsCount; i++)
             {
                 pairs.Add(new Tuple <uint, uint> (reader.ReadUInt32(), reader.ReadUInt32()));
             }
             Effects.Add(
                 new ALEffect()
             {
                 Name  = name,
                 CRC   = CrcTool.FLAleCrc(name),
                 Fx    = refs,
                 Pairs = pairs
             }
                 );
         }
     }
 }
示例#11
0
 public Material this[int i]
 {
     get
     {
         CheckNullArray();
         if (sph.sideMaterials[i] == null)
         {
             var crc = CrcTool.FLModelCrc(sph.sideMaterialNames[i]);
             sph.sideMaterials[i] = sph.library.FindMaterial(CrcTool.FLModelCrc(sph.sideMaterialNames[i]));
         }
         return(sph.sideMaterials[i]);
     }
     set
     {
         CheckNullArray();
         sph.sideMaterials[i] = value;
     }
 }
示例#12
0
 private void setMaterials(IntermediateNode materialLibraryNode)
 {
     //TODO: int count = 0;
     foreach (Node materialNode in materialLibraryNode)
     {
         if (materialNode is IntermediateNode)
         {
             uint materialId = CrcTool.FLModelCrc(materialNode.Name);
             if (!Materials.ContainsKey(materialId))
             {
                 Materials.Add(materialId, Material.FromNode(materialNode as IntermediateNode, this));
             }
         }
         //else if (subNode.Name.Equals("material count", StringComparison.OrdinalIgnoreCase))
         //count = (subNode as LeafNode).getIntegerBlaBLubb;
     }
     //if (count != materials.Count)
     //throw new Exception("Invalid material count: " + count + " != " + materials.Count);
 }
示例#13
0
 public static void DetectDrawable(string name, IDrawable drawable, ResourceManager res, List <MissingReference> missing, List <uint> matrefs, List <string> texrefs)
 {
     if (drawable is CmpFile)
     {
         var cmp = (CmpFile)drawable;
         foreach (var part in cmp.ModelParts())
         {
             DetectResourcesModel(part.Model, name + ", " + part.Model.Path, res, missing, matrefs, texrefs);
         }
     }
     if (drawable is ModelFile)
     {
         DetectResourcesModel((ModelFile)drawable, name, res, missing, matrefs, texrefs);
     }
     if (drawable is SphFile)
     {
         var sph = (SphFile)drawable;
         for (int i = 0; i < sph.SideMaterials.Length; i++)
         {
             if (sph.SideMaterials[i] != null && !sph.SideMaterials[i].Loaded)
             {
                 sph.SideMaterials[i] = null;
             }
             if (sph.SideMaterials[i] == null)
             {
                 var str = "Material: " + sph.SideMaterialNames[i];
                 if (!HasMissing(missing, str))
                 {
                     missing.Add(new MissingReference(str, string.Format("{0} M{1}", name, i)));
                 }
             }
             else
             {
                 var crc = CrcTool.FLModelCrc(sph.SideMaterialNames[i]);
                 if (!matrefs.Contains(crc))
                 {
                     matrefs.Add(crc);
                 }
                 DoMaterialRefs(sph.SideMaterials[i], res, missing, texrefs, string.Format(" - {0} M{1}", name, i));
             }
         }
     }
 }
示例#14
0
        public FxNode(AlchemyNode ale)
        {
            Name = ale.Name;
            AleParameter temp;

            if (ale.TryGetParameter("Node_Name", out temp))
            {
                NodeName = (string)temp.Value;
                CRC      = CrcTool.FLAleCrc(NodeName);
            }
            if (ale.TryGetParameter("Node_Transform", out temp))
            {
                Transform = (AlchemyTransform)temp.Value;
            }
            else
            {
                Transform = new AlchemyTransform();
            }
            if (ale.TryGetParameter("Node_LifeSpan", out temp))
            {
                NodeLifeSpan = (float)temp.Value;
            }
        }
示例#15
0
 private void setMeshes(IntermediateNode vMeshLibrary, ILibFile materialLibrary)
 {
     foreach (IntermediateNode vmsNode in vMeshLibrary)
     {
         var vMeshDataNode =
             vmsNode.FirstOrDefault(x => x.Name.Equals("VMeshData", StringComparison.OrdinalIgnoreCase));
         if (vMeshDataNode == null)
         {
             FLLog.Error("VMS", "Invalid VMeshLibrary: No VMeshData: " + vmsNode.Name);
             continue;
         }
         LeafNode vmsdat = vmsNode[0] as LeafNode;
         if (vmsdat == null)
         {
             FLLog.Error("VMS", "Invalid VMeshLibrary: VMeshData has no bytes: " + vmsNode.Name);
         }
         else
         {
             Meshes.Add(CrcTool.FLModelCrc(vmsNode.Name),
                        new VMeshData(vmsdat.DataSegment, materialLibrary, vmsNode.Name));
         }
     }
 }
示例#16
0
 public void DrawBuffer(CommandBuffer buffer, Matrix4 world, ref Lighting lighting, Material overrideMat = null)
 {
     if (SideMaterials.Length < 6)
     {
         return;
     }
     if (ready)
     {
         for (int i = 0; i < SideMaterials.Length; i++)
         {
             if (SideMaterials[i] != null && !SideMaterials[i].Loaded)
             {
                 SideMaterials[i].Loaded = false;
             }
         }
         for (int i = 0; i < 6; i++)
         {
             int     start, count;
             Vector3 pos;
             sphere.GetDrawParameters(faces[i], out start, out count, out pos);
             if (SideMaterials[i] == null)
             {
                 SideMaterials[i] = library.FindMaterial(CrcTool.FLModelCrc(sideMaterialNames[i]));
             }
             var mat = SideMaterials[i] ?? defaultMaterial;
             mat = overrideMat ?? mat;
             mat.Render.Camera = _camera;
             var transform = Matrix4.CreateScale(Radius) * world;
             buffer.AddCommand(
                 mat.Render,
                 null,
                 transform,
                 lighting,
                 sphere.VertexBuffer,
                 PrimitiveTypes.TriangleList,
                 0,
                 start,
                 count,
                 SortLayers.OBJECT
                 );
         }
         //Draw atmosphere
         if (SideMaterials.Length > 6 && overrideMat == null)
         {
             if (SideMaterials[6] == null)
             {
                 SideMaterials[6] = library.FindMaterial(CrcTool.FLModelCrc(sideMaterialNames[6]));
                 if (SideMaterials[6] == null)
                 {
                     return;
                 }
             }
             var mat       = (AtmosphereMaterial)SideMaterials[6].Render;
             var transform = Matrix4.CreateScale(Radius * mat.Scale) * world;
             for (int i = 0; i < 6; i++)
             {
                 int     start, count;
                 Vector3 pos;
                 sphere.GetDrawParameters(faces[i], out start, out count, out pos);
                 SideMaterials[6].Render.Camera = _camera;
                 buffer.AddCommand(
                     SideMaterials[6].Render,
                     null,
                     transform,
                     lighting,
                     sphere.VertexBuffer,
                     PrimitiveTypes.TriangleList,
                     0,
                     start,
                     count,
                     SortLayers.OBJECT,
                     RenderHelpers.GetZ(transform, _camera.Position, pos)
                     );
             }
         }
     }
     else
     {
         throw new Exception();
     }
 }
示例#17
0
        public byte[] VMeshData()
        {
            using (var stream = new MemoryStream())
            {
                var writer = new BinaryWriter(stream);
                writer.Write((uint)0x01);                 //MeshType
                writer.Write((uint)0x04);                 //SurfaceType
                writer.Write((ushort)(Drawcalls.Length)); //MeshCount
                writer.Write((ushort)(Indices.Length));   //IndexCount
                writer.Write((ushort)FVF);                //FVF
                writer.Write((ushort)Vertices.Length);    //VertexCount

                int startTri = 0;
                foreach (var dc in Drawcalls)
                {
                    //drawcalls must be sequential (start index isn't in VMeshData)
                    //this error shouldn't ever throw
                    if (startTri != dc.StartIndex)
                    {
                        throw new Exception("Invalid start index");
                    }
                    //write TMeshHeader
                    var crc = dc.Material != null?CrcTool.FLModelCrc(dc.Material.Name) : 0;

                    writer.Write(crc);
                    writer.Write((ushort)dc.StartVertex);
                    writer.Write((ushort)dc.EndVertex);
                    writer.Write((ushort)(dc.TriCount * 3)); //NumRefVertices
                    writer.Write((ushort)0);                 //Padding
                    //validation
                    startTri += dc.TriCount * 3;
                }

                foreach (var idx in Indices)
                {
                    writer.Write(idx);
                }
                foreach (var v in Vertices)
                {
                    writer.Write(v.Position.X);
                    writer.Write(v.Position.Y);
                    writer.Write(v.Position.Z);
                    if ((FVF & D3DFVF.NORMAL) == D3DFVF.NORMAL)
                    {
                        writer.Write(v.Normal.X);
                        writer.Write(v.Normal.Y);
                        writer.Write(v.Normal.Z);
                    }
                    if ((FVF & D3DFVF.DIFFUSE) == D3DFVF.DIFFUSE)
                    {
                        writer.Write(v.Diffuse);
                    }
                    //Librelancer stores texture coordinates flipped internally
                    if ((FVF & D3DFVF.TEX2) == D3DFVF.TEX2)
                    {
                        writer.Write(v.TextureCoordinate.X);
                        writer.Write(1 - v.TextureCoordinate.Y);
                        writer.Write(v.TextureCoordinateTwo.X);
                        writer.Write(1 - v.TextureCoordinateTwo.Y);
                    }
                    else if ((FVF & D3DFVF.TEX1) == D3DFVF.TEX1)
                    {
                        writer.Write(v.TextureCoordinate.X);
                        writer.Write(1 - v.TextureCoordinate.Y);
                    }
                }
                return(stream.ToArray());
            }
        }
示例#18
0
        public static byte[] VMeshData(Geometry g)
        {
            using (var stream = new MemoryStream())
            {
                var writer = new BinaryWriter(stream);
                writer.Write((uint)0x01);                 //MeshType
                writer.Write((uint)0x04);                 //SurfaceType
                writer.Write((ushort)(g.Groups.Length));  //MeshCount
                writer.Write((ushort)(g.Indices.Length)); //IndexCount
                D3DFVF fvf = FVF(g);
                writer.Write((ushort)fvf);                //FVF
                writer.Write((ushort)g.Vertices.Length);  //VertexCount

                int startTri = 0;
                foreach (var dc in g.Groups)
                {
                    //drawcalls must be sequential (start index isn't in VMeshData)
                    //this error shouldn't ever throw
                    if (startTri != dc.StartIndex)
                    {
                        throw new Exception("Invalid start index");
                    }
                    //write TMeshHeader
                    var crc = dc.Material != null?CrcTool.FLModelCrc(dc.Material.Name) : 0;

                    writer.Write(crc);
                    writer.Write((ushort)dc.BaseVertex);
                    int max = 0;
                    for (int i = 0; i < dc.IndexCount; i++)
                    {
                        max = Math.Max(max, g.Indices.Indices16[i + dc.StartIndex]);
                    }

                    max += dc.BaseVertex;
                    writer.Write((ushort)max);
                    writer.Write((ushort)dc.IndexCount); //NumRefVertices
                    writer.Write((ushort)0);             //Padding
                    //validation
                    startTri += dc.IndexCount;
                }

                foreach (var idx in g.Indices.Indices16)
                {
                    writer.Write(idx);
                }
                foreach (var v in g.Vertices)
                {
                    writer.Write(v.Position.X);
                    writer.Write(v.Position.Y);
                    writer.Write(v.Position.Z);
                    if ((fvf & D3DFVF.NORMAL) == D3DFVF.NORMAL)
                    {
                        writer.Write(v.Normal.X);
                        writer.Write(v.Normal.Y);
                        writer.Write(v.Normal.Z);
                    }
                    if ((fvf & D3DFVF.DIFFUSE) == D3DFVF.DIFFUSE)
                    {
                        writer.Write(((Color4)v.Diffuse).ToAbgr());
                    }
                    //Librelancer stores texture coordinates flipped internally
                    if ((fvf & D3DFVF.TEX2) == D3DFVF.TEX2)
                    {
                        writer.Write(v.Texture1.X);
                        writer.Write(1 - v.Texture1.Y);
                        writer.Write(v.Texture2.X);
                        writer.Write(1 - v.Texture2.Y);
                    }
                    else if ((fvf & D3DFVF.TEX1) == D3DFVF.TEX1)
                    {
                        writer.Write(v.Texture1.X);
                        writer.Write(1 - v.Texture1.Y);
                    }
                }
                return(stream.ToArray());
            }
        }
示例#19
0
        public AlchemyNodeLibrary(LeafNode utfleaf)
        {
            using (var reader = new BinaryReader(new MemoryStream(utfleaf.ByteArrayData))) {
                Version = reader.ReadSingle();
                int nodeCount = reader.ReadInt32();
                for (int nc = 0; nc < nodeCount; nc++)
                {
                    ushort nameLen  = reader.ReadUInt16();
                    var    nodeName = Encoding.ASCII.GetString(reader.ReadBytes(nameLen)).TrimEnd('\0');
                    reader.BaseStream.Seek(nameLen & 1, SeekOrigin.Current);                     //padding
                    var node = new AlchemyNode()
                    {
                        Name = nodeName
                    };
                    node.CRC = CrcTool.FLAleCrc(nodeName);
                    uint id, crc;
                    while (true)
                    {
                        id = reader.ReadUInt16();
                        if (id == 0)
                        {
                            break;
                        }
                        AleTypes type = (AleTypes)(id & 0x7FFF);
                        crc = reader.ReadUInt32();
                        string efname;
                        if (!AleCrc.FxCrc.TryGetValue(crc, out efname))
                        {
                            efname = string.Format("CRC: 0x{0:X}", crc);
                        }
                        object value = null;
                        switch (type)
                        {
                        case AleTypes.Boolean:
                            value = (id & 0x8000) != 0 ? true : false;
                            break;

                        case AleTypes.Integer:
                            value = reader.ReadUInt32();
                            break;

                        case AleTypes.Float:
                            value = reader.ReadSingle();
                            break;

                        case AleTypes.Name:
                            var vallen = reader.ReadUInt16();
                            if (vallen != 0)
                            {
                                value = Encoding.ASCII.GetString(reader.ReadBytes(vallen)).TrimEnd('\0');
                            }
                            reader.BaseStream.Seek(vallen & 1, SeekOrigin.Current);                             //padding
                            break;

                        case AleTypes.IPair:
                            value = new Tuple <uint, uint> (reader.ReadUInt32(), reader.ReadUInt32());
                            break;

                        case AleTypes.Transform:
                            value = new AlchemyTransform(reader);
                            break;

                        case AleTypes.FloatAnimation:
                            value = new AlchemyFloatAnimation(reader);
                            break;

                        case AleTypes.ColorAnimation:
                            value = new AlchemyColorAnimation(reader);
                            break;

                        case AleTypes.CurveAnimation:
                            value = new AlchemyCurveAnimation(reader);
                            break;

                        default:
                            throw new InvalidDataException("Invalid ALE Type: 0x" + (id & 0x7FFF).ToString("x"));
                        }
                        node.Parameters.Add(new AleParameter()
                        {
                            Name = efname, Value = value
                        });
                    }
                    AleParameter temp;
                    if (node.TryGetParameter("Node_Name", out temp))
                    {
                        var nn = (string)temp.Value;
                        node.CRC = CrcTool.FLAleCrc(nn);
                    }
                    Nodes.Add(node);
                }
            }
        }
示例#20
0
 void DoNodeMenu(string id, LUtfNode node, LUtfNode parent)
 {
     if (ImGui.BeginPopupContextItem(id))
     {
         ImGui.MenuItem(node.Name, false);
         ImGui.MenuItem(string.Format("CRC: 0x{0:X}", CrcTool.FLModelCrc(node.Name)), false);
         ImGui.Separator();
         if (Theme.IconMenuItem(Icons.Edit, "Rename", node != Utf.Root))
         {
             text.SetText(node.Name);
             renameNode = node;
             popups.OpenPopup("Rename Node");
         }
         if (Theme.IconMenuItem(Icons.TrashAlt, "Delete", node != Utf.Root))
         {
             deleteParent = parent;
             deleteNode   = node;
             Confirm("Are you sure you want to delete: '" + node.Name + "'?", () =>
             {
                 if (selectedNode == deleteNode)
                 {
                     selectedNode = null;
                 }
                 deleteParent.Children.Remove(deleteNode);
             });
         }
         if (Theme.IconMenuItem(Icons.Eraser, "Clear", node.Children != null || node.Data != null))
         {
             clearNode = node;
             Confirm("Clearing this node will delete all data and children. Continue?", () =>
             {
                 clearNode.Data = null;
                 if (clearNode == Utf.Root)
                 {
                     clearNode.Children = new List <LUtfNode>();
                 }
                 else
                 {
                     clearNode.Children = null;
                 }
             });
         }
         ImGui.Separator();
         if (Theme.BeginIconMenu(Icons.PlusCircle, "Add"))
         {
             if (ImGui.MenuItem("Child"))
             {
                 text.SetText("");
                 addParent = null;
                 addNode   = node;
                 if (node.Data != null)
                 {
                     Confirm("Adding a node will clear data. Continue?", () =>
                     {
                         popups.OpenPopup("New Node");
                     });
                 }
                 else
                 {
                     popups.OpenPopup("New Node");
                 }
             }
             if (ImGui.MenuItem("Before", node != Utf.Root))
             {
                 text.SetText("");
                 addParent = parent;
                 addNode   = node;
                 addOffset = 0;
                 popups.OpenPopup("New Node");
             }
             if (ImGui.MenuItem("After", node != Utf.Root))
             {
                 text.SetText("");
                 addParent = parent;
                 addNode   = node;
                 addOffset = 1;
                 popups.OpenPopup("New Node");
             }
             ImGui.EndMenu();
         }
         ImGui.Separator();
         if (Theme.IconMenuItem(Icons.Cut, "Cut", node != Utf.Root))
         {
             parent.Children.Remove(node);
             main.ClipboardCopy = false;
             main.Clipboard     = node;
         }
         if (Theme.IconMenuItem(Icons.Copy, "Copy", node != Utf.Root))
         {
             main.ClipboardCopy = true;
             main.Clipboard     = node.MakeCopy();
         }
         if (main.Clipboard != null)
         {
             if (Theme.BeginIconMenu(Icons.Paste, "Paste"))
             {
                 if (ImGui.MenuItem("Before", node != Utf.Root))
                 {
                     if (main.ClipboardCopy)
                     {
                         var cpy = main.Clipboard.MakeCopy();
                         cpy.Parent = parent;
                         parent.Children.Insert(parent.Children.IndexOf(node), cpy);
                     }
                     else
                     {
                         main.Clipboard.Parent = parent;
                         parent.Children.Insert(parent.Children.IndexOf(node), main.Clipboard);
                         main.Clipboard = null;
                     }
                 }
                 if (ImGui.MenuItem("After", node != Utf.Root))
                 {
                     if (main.ClipboardCopy)
                     {
                         var cpy = main.Clipboard.MakeCopy();
                         cpy.Parent = parent;
                         parent.Children.Insert(parent.Children.IndexOf(node) + 1, cpy);
                     }
                     else
                     {
                         main.Clipboard.Parent = parent;
                         parent.Children.Insert(parent.Children.IndexOf(node) + 1, main.Clipboard);
                         main.Clipboard = null;
                     }
                 }
                 if (ImGui.MenuItem("Into"))
                 {
                     if (node.Data == null)
                     {
                         if (node.Children == null)
                         {
                             node.Children = new List <LUtfNode>();
                         }
                         if (main.ClipboardCopy)
                         {
                             var cpy = main.Clipboard.MakeCopy();
                             cpy.Parent = node;
                             node.Children.Add(cpy);
                         }
                         else
                         {
                             main.Clipboard.Parent = node;
                             node.Children.Add(main.Clipboard);
                             main.Clipboard = null;
                         }
                     }
                     else
                     {
                         pasteInto = node;
                         Confirm("Adding children will delete this node's data. Continue?", () =>
                         {
                             pasteInto.Data     = null;
                             pasteInto.Children = new List <LUtfNode>();
                             if (main.ClipboardCopy)
                             {
                                 var cpy    = main.Clipboard.MakeCopy();
                                 cpy.Parent = pasteInto;
                                 pasteInto.Children.Add(cpy);
                             }
                             else
                             {
                                 main.Clipboard.Parent = pasteInto;
                                 pasteInto.Children.Add(main.Clipboard);
                                 main.Clipboard = null;
                             }
                         });
                     }
                 }
                 ImGui.EndMenu();
             }
         }
         else
         {
             Theme.IconMenuItem(Icons.Paste, "Paste", false);
         }
         ImGui.EndPopup();
     }
 }
示例#21
0
        public static Model3D LoadModel(string file)
        {
            UtfManager utfManager = new UtfManager(file);
            UtfNode    root       = utfManager.Read();

            if (root == null || root.Nodes.Count == 0)
            {
                return(null);
            }

            // select root (\) node
            root = root.Nodes[0];

            Dictionary <uint, VMeshData> meshes             = null;
            List <MeshReferenceMatch>    meshReferenceNodes = new List <MeshReferenceMatch>();
            List <CmpPart> constructs = new List <CmpPart>();
            Dictionary <string, string> mapFileToObj = new Dictionary <string, string>
            {
                { "\\", "Model" }
            };

            foreach (UtfNode node in root.Nodes)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "vmeshlibrary":
                    meshes = new Dictionary <uint, VMeshData>(node.Nodes.Count);
                    foreach (UtfNode vmsNode in node.Nodes)
                    {
                        if (vmsNode.Nodes.Count > 0)
                        {
                            meshes.Add(CrcTool.FlModelCrc(vmsNode.Name), new VMeshData(vmsNode.Nodes[0].Data));
                        }
                    }

                    break;

                case "cmpnd":
                    foreach (UtfNode cmpndNode in node.Nodes)
                    {
                        if (cmpndNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase))
                        {
                            foreach (UtfNode constructNode in cmpndNode.Nodes)
                            {
                                switch (constructNode.Name.ToLowerInvariant())
                                {
                                case "fix":
                                    FixConstruct.Parse(constructs, constructNode.Data);
                                    break;

                                case "rev":
                                    RevConstruct.Parse(constructs, constructNode.Data);
                                    break;

                                case "pris":
                                    PrisConstruct.Parse(constructs, constructNode.Data);
                                    break;

                                case "sphere":
                                    SphereConstruct.Parse(constructs, constructNode.Data);
                                    break;
                                }
                            }
                        }
                        else if (cmpndNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) ||
                                 cmpndNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase))
                        {
                            string objectName = null;
                            string fileName   = null;

                            // int index = -1;
                            foreach (UtfNode partNode in cmpndNode.Nodes)
                            {
                                switch (partNode.Name.ToLowerInvariant())
                                {
                                case "object name":
                                    objectName = Encoding.ASCII.GetString(partNode.Data).TrimEnd('\0');
                                    break;

                                case "file name":
                                    fileName = Encoding.ASCII.GetString(partNode.Data).TrimEnd('\0');
                                    break;

                                    // case "index":
                                    // index = BitConverter.ToInt32(partNode.Data, 0);
                                    // break;
                                }
                            }

                            if (objectName != null && fileName != null)
                            {
                                mapFileToObj[fileName] = objectName;
                            }
                        }
                    }

                    break;

                case "multilevel":
                    // multi LoD 3db model (\MultiLevel\Level0\VMeshPart\VMeshRef => \)
                    VMeshRef meshReference2 = ParseMultiLevelNode(node);
                    if (meshReference2 != null)
                    {
                        meshReferenceNodes.Add(new MeshReferenceMatch {
                            FileName = "\\", MeshReference = meshReference2
                        });
                    }

                    break;

                case "vmeshpart":
                    // single LoD 3db model (\VMeshPart\VMeshRef => \)
                    VMeshRef meshReference3 = ParseMeshPartNode(node);
                    if (meshReference3 != null)
                    {
                        meshReferenceNodes.Add(new MeshReferenceMatch {
                            FileName = "\\", MeshReference = meshReference3
                        });
                    }

                    break;

                default:
                    if (node.Name.EndsWith(".3db", StringComparison.OrdinalIgnoreCase))
                    {
                        foreach (UtfNode subNode in node.Nodes)
                        {
                            if (subNode.Name.Equals("multilevel", StringComparison.OrdinalIgnoreCase))
                            {
                                // multi LoD cmp model (\PARTNAME.3db\MultiLevel\Level0\VMeshPart\VMeshRef => PARTNAME.3db)
                                VMeshRef meshReference = ParseMultiLevelNode(subNode);
                                if (meshReference != null)
                                {
                                    meshReferenceNodes.Add(new MeshReferenceMatch {
                                        FileName = node.Name, MeshReference = meshReference
                                    });
                                }

                                break;
                            }

                            if (subNode.Name.Equals("vmeshpart", StringComparison.OrdinalIgnoreCase))
                            {
                                // single LoD cmp model (\PARTNAME.3db\VMeshPart\VMeshRef => PARTNAME.3db)
                                VMeshRef meshReference = ParseMeshPartNode(subNode);
                                if (meshReference != null)
                                {
                                    meshReferenceNodes.Add(new MeshReferenceMatch {
                                        FileName = node.Name, MeshReference = meshReference
                                    });
                                }

                                break;
                            }
                        }
                    }

                    break;
                }
            }

            if (meshes == null || meshReferenceNodes.Count == 0)
            {
                return(null);
            }

            List <MeshGroup> meshGroups = new List <MeshGroup>();

            foreach (MeshReferenceMatch meshReferenceNode in meshReferenceNodes)
            {
                string meshGroupName;
                if (mapFileToObj.TryGetValue(meshReferenceNode.FileName, out meshGroupName))
                {
                    VMeshData mesh;
                    if (meshes.TryGetValue(meshReferenceNode.MeshReference.VMeshLibId, out mesh))
                    {
                        meshGroups.Add(new MeshGroup
                        {
                            MeshReference = meshReferenceNode.MeshReference,
                            Mesh          = mesh,
                            Transform     = GetTransform(constructs, meshGroupName)
                        });
                    }
                }
            }

            return(GetCmpModelGroup(meshGroups));
        }
 void ProcessSur(LibreLancer.Physics.Sur.SurFile surfile)
 {
     if (surs != null)
     {
         foreach (var mdl in surs)
         {
             mdl.Vertices.Dispose();
             mdl.Elements.Dispose();
         }
     }
     surs = new List <SurModel>();
     if ((drawable is ModelFile))
     {
         surs.Add(GetSurModel(surfile.GetMesh(0, false), null, surPart));
         foreach (var hpid in surfile.HardpointIds)
         {
             surs.Add(GetSurModel(surfile.GetMesh(hpid, true), null, surHardpoint));
         }
     }
     else
     {
         Dictionary <uint, SurModel> crcLookup = new Dictionary <uint, SurModel>();
         foreach (var part in ((CmpFile)drawable).Parts)
         {
             crcLookup.Add(CrcTool.FLModelCrc(part.ObjectName), new SurModel()
             {
                 Part = part
             });
         }
         foreach (var part in ((CmpFile)drawable).Parts)
         {
             var crc = CrcTool.FLModelCrc(part.ObjectName);
             foreach (var msh in surfile.GetMesh(crc, false))
             {
                 AddVertices(crcLookup[msh.ParentCrc], msh);
             }
             foreach (var hp in part.Model.Hardpoints)
             {
                 crc = CrcTool.FLModelCrc(hp.Name);
                 Color4 c = surHardpoint;
                 if (hp.Name.Equals("hpmount", StringComparison.OrdinalIgnoreCase))
                 {
                     c = surShield;
                 }
                 if (surfile.HardpointIds.Contains(crc))
                 {
                     surs.Add(GetSurModel(surfile.GetMesh(crc, true), null, c));
                 }
             }
         }
         foreach (var mdl in crcLookup.Values)
         {
             mdl.Vertices = new VertexBuffer(typeof(VertexPositionColor), mdl.BuildVertices.Count);
             mdl.Vertices.SetData(mdl.BuildVertices.ToArray());
             mdl.BuildVertices = null;
             mdl.Elements      = new ElementBuffer(mdl.BuildIndices.Count);
             mdl.Elements.SetData(mdl.BuildIndices.ToArray());
             mdl.Vertices.SetElementBuffer(mdl.Elements);
             mdl.BuildIndices = null;
             surs.Add(mdl);
         }
     }
 }