Example #1
0
        public async Task <IActionResult> Update([FromBody] Model.Variant variant)
        {
            try
            {
                var isUpdated = await _coreVariant.Update(variant);

                if (isUpdated)
                {
                    return(Ok(variant));
                }
                return(BadRequest());
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }
        }
Example #2
0
 public async Task <Model.Variant> Get(long id)
 {
     Model.Variant variant = null;
     try
     {
         variant = await _context.Variants
                   .Include(x => x.Status)
                   .Include(x => x.Options)
                   .Include(x => x.Parameter)
                   .Include(x => x.Product)
                   .Include(x => x.Taxe)
                   .Include(x => x.Image)
                   .Include(x => x.Supplier)
                   .FirstOrDefaultAsync(x => x.Id == Convert.ToInt64(id));
     }
     catch (Exception ex)
     {
         throw new Exception(ex.Message);
     }
     return(variant);
 }
Example #3
0
        public async Task <Boolean> Update(Model.Variant variant)
        {
            Boolean result = false;

            try
            {
                if (variant != null)
                {
                    variant.UpdatedOn = DateTime.Now;
                    if (variant.Status != null && variant.Status.Id != 0)
                    {
                        variant.StatusId = variant.Status.Id;
                    }
                    if (variant.Parameter != null && variant.Parameter.Id != 0)
                    {
                        variant.ParameterId = variant.Parameter.Id;
                    }
                    if (variant.Taxe != null && variant.Taxe.Id != 0)
                    {
                        variant.TaxeId = variant.Taxe.Id;
                    }
                    if (variant.Image != null && string.IsNullOrEmpty(variant.Image.PathUrl))
                    {
                        variant.ImageId = variant.Image.Id;
                    }
                    if (variant.Supplier != null && variant.Supplier.Id != 0)
                    {
                        variant.SupplierId = variant.Supplier.Id;
                    }

                    _context.Variants.Update(variant);
                    result = await _context.SaveChangesAsync() > 0;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return(result);
        }
Example #4
0
        public RenderObject(D3DDevice device, HaloOnlineCacheContext cacheContext, GameObject definition, RealPoint3d position, RealEulerAngles3d rotation)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }
            else if (cacheContext == null)
            {
                throw new ArgumentNullException(nameof(cacheContext));
            }
            else if (definition == null)
            {
                throw new ArgumentNullException(nameof(definition));
            }

            Device       = device;
            CacheContext = cacheContext;
            Object       = definition;

            Position = position;
            Rotation = rotation;
            UpdateTransform();

            using (var cacheStream = CacheContext.OpenTagCacheRead())
            {
                if (Object.Model == null)
                {
                    throw new NullReferenceException(nameof(Object.Model));
                }

                Model = CacheContext.Deserialize <Model>(new TagSerializationContext(cacheStream, CacheContext, Object.Model));

                if (Model.RenderModel == null)
                {
                    throw new NullReferenceException(nameof(Model.RenderModel));
                }

                RenderModel = CacheContext.Deserialize <RenderModel>(new TagSerializationContext(cacheStream, CacheContext, Model.RenderModel));

                if (Model.Variants == null || Model.Variants.Count == 0)
                {
                    var modelVariant = new Model.Variant
                    {
                        Name    = CacheContext.GetStringId("default"),
                        Regions = new List <Model.Variant.Region>()
                    };

                    foreach (var region in RenderModel.Regions)
                    {
                        var modelRegion = new Model.Variant.Region
                        {
                            Name = region.Name,
                            RenderModelRegionIndex = (sbyte)RenderModel.Regions.IndexOf(region),
                            Permutations           = new List <Model.Variant.Region.Permutation>()
                        };

                        foreach (var permutation in region.Permutations)
                        {
                            modelRegion.Permutations.Add(new Model.Variant.Region.Permutation
                            {
                                Name = modelVariant.Name,
                                RenderModelPermutationIndex = (sbyte)region.Permutations.IndexOf(permutation)
                            });
                        }

                        modelVariant.Regions.Add(modelRegion);
                    }

                    Model.Variants = new List <Model.Variant> {
                        modelVariant
                    };
                }

                Materials = new List <RenderMaterial>();

                foreach (var material in RenderModel.Materials)
                {
                    Materials.Add(new RenderMaterial(device, CacheContext, material));
                }

                if (RenderModel.Geometry.Resource == null)
                {
                    throw new NullReferenceException(nameof(RenderModel.Geometry.Resource));
                }

                RenderGeometryResource = CacheContext.Deserialize <RenderGeometryApiResourceDefinition>(RenderModel.Geometry.Resource);

                using (var resourceStream = new MemoryStream())
                    using (var reader = new BinaryReader(resourceStream))
                    {
                        CacheContext.ExtractResource(RenderModel.Geometry.Resource, resourceStream);

                        VertexBuffers = new Dictionary <int, VertexBuffer>();
                        IndexBuffers  = new Dictionary <int, IndexBuffer>();

                        var compression = RenderModel.Geometry.Compression[0];

                        foreach (var mesh in RenderModel.Geometry.Meshes)
                        {
                            var renderVertex = VertexDefinition.Get(mesh.Type);
                            var streamTypes  = renderVertex.GetStreamTypes();

                            foreach (var streamEntry in streamTypes)
                            {
                                var vertexBufferIndex = mesh.VertexBufferIndices[streamEntry.Key];

                                if (vertexBufferIndex == ushort.MaxValue || VertexBuffers.ContainsKey(vertexBufferIndex))
                                {
                                    continue;
                                }

                                var vbDef = RenderGeometryResource.VertexBuffers[vertexBufferIndex].Definition;

                                var vb     = new VertexBuffer(streamEntry.Value, vbDef.Data.Size, device, Usage.DoNotClip, renderVertex.GetStreamFormat(streamEntry.Key), Pool.Managed);
                                var vbData = vb.Lock(0, vbDef.Data.Size, LockFlags.None);

                                resourceStream.Position = vbDef.Data.Address.Offset;

                                var vertices = Array.CreateInstance(streamEntry.Value, vbDef.Count);

                                for (var i = 0; i < vbDef.Count; i++)
                                {
                                    var handle = GCHandle.Alloc(reader.ReadBytes(Marshal.SizeOf(streamEntry.Value)), GCHandleType.Pinned);
                                    var vertex = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), streamEntry.Value);

                                    var positionField = streamEntry.Value.GetField("Position");

                                    if (positionField != null)
                                    {
                                        var xyz = (Vector3)positionField.GetValue(vertex);

                                        positionField.SetValue(vertex, new Vector3(
                                                                   xyz.X * compression.X.Length + compression.X.Lower,
                                                                   xyz.Y * compression.Y.Length + compression.Y.Lower,
                                                                   xyz.Z * compression.Z.Length + compression.Z.Lower));
                                    }

                                    var texcoordField = streamEntry.Value.GetField("Texcoord");

                                    if (texcoordField != null)
                                    {
                                        var uv = (Vector2)texcoordField.GetValue(vertex);

                                        texcoordField.SetValue(vertex, new Vector2(
                                                                   uv.X * compression.U.Length + compression.U.Lower,
                                                                   uv.Y * compression.V.Length + compression.V.Lower));
                                    }

                                    vertices.SetValue(vertex, i);

                                    handle.Free();
                                }

                                vbData.Write(vertices);
                                vb.Unlock();

                                VertexBuffers[vertexBufferIndex] = vb;
                            }

                            foreach (var indexBufferIndex in mesh.IndexBufferIndices)
                            {
                                if (indexBufferIndex == ushort.MaxValue || IndexBuffers.ContainsKey(indexBufferIndex))
                                {
                                    continue;
                                }

                                var ibDef = RenderGeometryResource.IndexBuffers[indexBufferIndex].Definition;

                                switch (ibDef.Format)
                                {
                                case IndexBufferFormat.PointList:
                                    mesh.IndexBufferType = TagPrimitiveType.PointList;
                                    break;

                                case IndexBufferFormat.LineList:
                                    mesh.IndexBufferType = TagPrimitiveType.LineList;
                                    break;

                                case IndexBufferFormat.LineStrip:
                                    mesh.IndexBufferType = TagPrimitiveType.LineStrip;
                                    break;

                                case IndexBufferFormat.TriangleList:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleList;
                                    break;

                                case IndexBufferFormat.TriangleFan:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleFan;
                                    break;

                                case IndexBufferFormat.TriangleStrip:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleStrip;
                                    break;
                                }

                                var ib     = new IndexBuffer(device, ibDef.Data.Size, Usage.DoNotClip, Pool.Managed, true);
                                var ibData = ib.Lock(0, ibDef.Data.Size, LockFlags.None);

                                resourceStream.Position = ibDef.Data.Address.Offset;

                                var indices = new ushort[ibDef.Data.Size / 2];

                                for (var i = 0; i < ibDef.Data.Size / 2; i++)
                                {
                                    indices[i] = reader.ReadUInt16();
                                }

                                ibData.Write(indices);
                                ib.Unlock();

                                IndexBuffers[indexBufferIndex] = ib;
                            }
                        }
                    }
            }
        }
Example #5
0
        private void ExtractAmf(FileInfo modelFile, RenderModel renderModel, Model.Variant modelVariant, RenderGeometryApiResourceDefinition resourceDefinition, Stream resourceStream)
        {
            using (var amfStream = modelFile.Create())
                using (var amfWriter = new EndianWriter(amfStream))
                {
                    var dupeDic = new Dictionary <int, int>();

                    var indxAddressList = new List <int>();
                    var indxValueList   = new List <int>();

                    var meshAddressList = new List <int>();
                    var meshValueList   = new List <int>();

                    var regions      = new List <RenderModel.Region>();
                    var permutations = new List <RenderModel.Region.Permutation>();

                    foreach (var variantRegion in modelVariant.Regions)
                    {
                        if (variantRegion.RenderModelRegionIndex == -1)
                        {
                            continue;
                        }

                        var region = renderModel.Regions[variantRegion.RenderModelRegionIndex];
                        var variantPermutations = region.Permutations.Where(i => variantRegion.Permutations.Find(j => j.Name == i.Name) != null).ToList();

                        if (variantPermutations.Count == 0)
                        {
                            continue;
                        }

                        if (!regions.Contains(region))
                        {
                            regions.Add(region);
                        }

                        foreach (var variantPermutation in variantPermutations)
                        {
                            if (!permutations.Contains(variantPermutation))
                            {
                                permutations.Add(variantPermutation);
                            }
                        }
                    }

                    var headerAddressList = new List <int>();
                    var headerValueList   = new List <int>();

                    amfWriter.Write("AMF!".ToCharArray());
                    amfWriter.Write(2.0f); //format version
                    amfWriter.Write((CacheContext.GetString(renderModel.Name) + "\0").ToCharArray());

                    amfWriter.Write(renderModel.Nodes.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    amfWriter.Write(renderModel.MarkerGroups.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    amfWriter.Write(regions.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    amfWriter.Write(renderModel.Materials.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    headerValueList.Add((int)amfWriter.BaseStream.Position);

                    foreach (var node in renderModel.Nodes)
                    {
                        amfWriter.Write((CacheContext.GetString(node.Name) + "\0").ToCharArray());
                        amfWriter.Write(node.ParentNode);
                        amfWriter.Write(node.FirstChildNode);
                        amfWriter.Write(node.NextSiblingNode);
                        amfWriter.Write(node.DefaultTranslation.X * 100);
                        amfWriter.Write(node.DefaultTranslation.Y * 100);
                        amfWriter.Write(node.DefaultTranslation.Z * 100);
                        amfWriter.Write(node.DefaultRotation.I);
                        amfWriter.Write(node.DefaultRotation.J);
                        amfWriter.Write(node.DefaultRotation.K);
                        amfWriter.Write(node.DefaultRotation.W);
                    }

                    var markerAddressList = new List <int>();
                    var markerValueList   = new List <int>();

                    headerValueList.Add((int)amfWriter.BaseStream.Position);

                    foreach (var group in renderModel.MarkerGroups)
                    {
                        amfWriter.Write((CacheContext.GetString(group.Name) + "\0").ToCharArray());
                        amfWriter.Write(group.Markers.Count);
                        markerAddressList.Add((int)amfWriter.BaseStream.Position);
                        amfWriter.Write(0);
                    }

                    foreach (var group in renderModel.MarkerGroups)
                    {
                        markerValueList.Add((int)amfWriter.BaseStream.Position);
                        foreach (var marker in group.Markers)
                        {
                            amfWriter.Write((byte)marker.RegionIndex);
                            amfWriter.Write((byte)marker.PermutationIndex);
                            amfWriter.Write((short)marker.NodeIndex);
                            amfWriter.Write(marker.Translation.X * 100);
                            amfWriter.Write(marker.Translation.Y * 100);
                            amfWriter.Write(marker.Translation.Z * 100);
                            amfWriter.Write(marker.Rotation.I);
                            amfWriter.Write(marker.Rotation.J);
                            amfWriter.Write(marker.Rotation.K);
                            amfWriter.Write(marker.Rotation.W);
                        }
                    }

                    var permAddressList = new List <int>();
                    var permValueList   = new List <int>();

                    headerValueList.Add((int)amfWriter.BaseStream.Position);

                    foreach (var variantRegion in modelVariant.Regions)
                    {
                        if (variantRegion.RenderModelRegionIndex == -1)
                        {
                            continue;
                        }

                        var region = renderModel.Regions[variantRegion.RenderModelRegionIndex];
                        var variantPermutations = region.Permutations.Where(i => variantRegion.Permutations.Find(j => j.Name == i.Name) != null).ToList();

                        if (variantPermutations.Count == 0)
                        {
                            continue;
                        }

                        amfWriter.Write((CacheContext.GetString(region.Name) + "\0").ToCharArray());
                        amfWriter.Write(variantPermutations.Count);
                        permAddressList.Add((int)amfWriter.BaseStream.Position);
                        amfWriter.Write(0);
                    }

                    var vertAddressList = new List <int>();
                    var vertValueList   = new List <int>();

                    /*
                     * foreach (var variantRegion in modelVariant.Regions)
                     * {
                     *  if (variantRegion.RenderModelRegionIndex == -1)
                     *      continue;
                     *
                     *  var region = renderModel.Regions[variantRegion.RenderModelRegionIndex];
                     *  var variantPermutations = region.Permutations.Where(i => variantRegion.Permutations.Find(j => j.Name == i.Name) != null).ToList();
                     *
                     *  if (variantPermutations.Count == 0)
                     *      continue;
                     *
                     *  permValueList.Add((int)amfWriter.BaseStream.Position);
                     *
                     *  foreach (var permutation in variantPermutations)
                     *  {
                     *      if (permutation.MeshIndex == -1)
                     *          continue;
                     *
                     *      var mesh = renderModel.Geometry.Meshes[permutation.MeshIndex];
                     *
                     *      amfWriter.Write((CacheContext.GetString(permutation.Name) + "\0").ToCharArray());
                     *      amfWriter.Write((byte)(mesh.RigidNodeIndex == -1 ? 1 : 0));
                     *      amfWriter.Write((byte)mesh.RigidNodeIndex);
                     *
                     *      var vertexCount = 0;
                     *      var indexCount = 0;
                     *      foreach (var part in mesh.Parts)
                     *      {
                     *          vertexCount += part.VertexCount;
                     *          indexCount += part.IndexCount;
                     *      }
                     *
                     *      amfWriter.Write(vertexCount);
                     *      vertAddressList.Add((int)amfWriter.BaseStream.Position);
                     *      amfWriter.Write(0);
                     *
                     *      amfWriter.Write(indexCount);
                     *      indxAddressList.Add((int)amfWriter.BaseStream.Position);
                     *      amfWriter.Write(0);
                     *
                     *      amfWriter.Write(mesh.SubParts.Count);
                     *      meshAddressList.Add((int)amfWriter.BaseStream.Position);
                     *      amfWriter.Write(0);
                     *
                     *      amfWriter.Write(float.NaN);
                     *  }
                     * }
                     *
                     * foreach (var variantRegion in modelVariant.Regions)
                     * {
                     *  if (variantRegion.RenderModelRegionIndex == -1)
                     *      continue;
                     *
                     *  var region = renderModel.Regions[variantRegion.RenderModelRegionIndex];
                     *  var variantPermutations = region.Permutations.Where(i => variantRegion.Permutations.Find(j => j.Name == i.Name) != null).ToList();
                     *
                     *  if (variantPermutations.Count == 0)
                     *      continue;
                     *
                     *  foreach (var permutation in variantPermutations)
                     *  {
                     *      if (permutation.MeshIndex == -1)
                     *          continue;
                     *
                     *      var mesh = renderModel.Geometry.Meshes[permutation.MeshIndex];
                     *
                     *      if (dupeDic.TryGetValue(mesh.VertexBuffers[0], out int address))
                     *      {
                     *          vertValueList.Add(address);
                     *          continue;
                     *      }
                     *      else
                     *          dupeDic.Add(mesh.VertexBuffers[0], (int)amfWriter.BaseStream.Position);
                     *
                     *      var hasNodes = mesh.RigidNodeIndex == -1;
                     *
                     *      vertValueList.Add((int)amfWriter.BaseStream.Position);
                     *
                     *      foreach (Vertex vert in part.Vertices)
                     *      {
                     *          vert.TryGetValue("position", 0, out v);
                     *          amfWriter.Write(v.Data.x * 100);
                     *          amfWriter.Write(v.Data.y * 100);
                     *          amfWriter.Write(v.Data.z * 100);
                     *
                     *          vert.TryGetValue("normal", 0, out v);
                     *          amfWriter.Write(v.Data.i);
                     *          amfWriter.Write(v.Data.j);
                     *          amfWriter.Write(v.Data.k);
                     *
                     *          vert.TryGetValue("texcoords", 0, out v);
                     *          amfWriter.Write(v.Data.x);
                     *          amfWriter.Write(v.Data.y);
                     *
                     *          if (hasNodes)
                     *          {
                     *              VertexValue i, w;
                     *              vert.TryGetValue("blendindices", 0, out i);
                     *              vert.TryGetValue("blendweight", 0, out w);
                     *              int count = 0;
                     *              if (w.Data.a > 0)
                     *              {
                     *                  amfWriter.Write((byte)i.Data.a);
                     *                  count++;
                     *              }
                     *              if (w.Data.b > 0)
                     *              {
                     *                  amfWriter.Write((byte)i.Data.b);
                     *                  count++;
                     *              }
                     *              if (w.Data.c > 0)
                     *              {
                     *                  amfWriter.Write((byte)i.Data.c);
                     *                  count++;
                     *              }
                     *              if (w.Data.d > 0)
                     *              {
                     *                  amfWriter.Write((byte)i.Data.d);
                     *                  count++;
                     *              }
                     *
                     *              if (count == 0)
                     *              {
                     *                  amfWriter.Write((byte)0);
                     *                  amfWriter.Write((byte)255);
                     *                  amfWriter.Write(0);
                     *                  continue;
                     *                  //throw new Exception("no weights on a weighted node. report ");
                     *              }
                     *
                     *              if (count != 4) amfWriter.Write((byte)255);
                     *
                     *              if (w.Data.a > 0) amfWriter.Write(w.Data.a);
                     *              if (w.Data.b > 0) amfWriter.Write(w.Data.b);
                     *              if (w.Data.c > 0) amfWriter.Write(w.Data.c);
                     *              if (w.Data.d > 0) amfWriter.Write(w.Data.d);
                     *          }
                     *      }
                     *  }
                     * }
                     *
                     * foreach (var perm in permutations)
                     * {
                     *  var part = renderModel.ModelSections[perm.PieceIndex];
                     *
                     *  int address;
                     *  if (dupeDic.TryGetValue(part.VertsIndex, out address))
                     *  {
                     *      vertValueList.Add(address);
                     *      continue;
                     *  }
                     *  else
                     *      dupeDic.Add(part.VertsIndex, (int)amfWriter.BaseStream.Position);
                     *
                     *  VertexValue v;
                     *  bool hasNodes = part.Vertices[0].TryGetValue("blendindices", 0, out v) && part.NodeIndex == 255;
                     *
                     *  vertValueList.Add((int)amfWriter.BaseStream.Position);
                     *
                     *  foreach (Vertex vert in part.Vertices)
                     *  {
                     *      vert.TryGetValue("position", 0, out v);
                     *      amfWriter.Write(v.Data.x * 100);
                     *      amfWriter.Write(v.Data.y * 100);
                     *      amfWriter.Write(v.Data.z * 100);
                     *
                     *      vert.TryGetValue("normal", 0, out v);
                     *      amfWriter.Write(v.Data.i);
                     *      amfWriter.Write(v.Data.j);
                     *      amfWriter.Write(v.Data.k);
                     *
                     *      vert.TryGetValue("texcoords", 0, out v);
                     *      amfWriter.Write(v.Data.x);
                     *      amfWriter.Write(v.Data.y);
                     *
                     *      if (hasNodes)
                     *      {
                     *          VertexValue i, w;
                     *          vert.TryGetValue("blendindices", 0, out i);
                     *          vert.TryGetValue("blendweight", 0, out w);
                     *          int count = 0;
                     *          if (w.Data.a > 0)
                     *          {
                     *              amfWriter.Write((byte)i.Data.a);
                     *              count++;
                     *          }
                     *          if (w.Data.b > 0)
                     *          {
                     *              amfWriter.Write((byte)i.Data.b);
                     *              count++;
                     *          }
                     *          if (w.Data.c > 0)
                     *          {
                     *              amfWriter.Write((byte)i.Data.c);
                     *              count++;
                     *          }
                     *          if (w.Data.d > 0)
                     *          {
                     *              amfWriter.Write((byte)i.Data.d);
                     *              count++;
                     *          }
                     *
                     *          if (count == 0)
                     *          {
                     *              amfWriter.Write((byte)0);
                     *              amfWriter.Write((byte)255);
                     *              amfWriter.Write(0);
                     *              continue;
                     *              //throw new Exception("no weights on a weighted node. report ");
                     *          }
                     *
                     *          if (count != 4) amfWriter.Write((byte)255);
                     *
                     *          if (w.Data.a > 0) amfWriter.Write(w.Data.a);
                     *          if (w.Data.b > 0) amfWriter.Write(w.Data.b);
                     *          if (w.Data.c > 0) amfWriter.Write(w.Data.c);
                     *          if (w.Data.d > 0) amfWriter.Write(w.Data.d);
                     *      }
                     *  }
                     * }
                     #endregion
                     *
                     * dupeDic.Clear();
                     *
                     #region Indices
                     * foreach (var perm in permutations)
                     * {
                     *  var part = renderModel.ModelSections[perm.PieceIndex];
                     *
                     *  int address;
                     *  if (dupeDic.TryGetValue(part.FacesIndex, out address))
                     *  {
                     *      indxValueList.Add(address);
                     *      continue;
                     *  }
                     *  else
                     *      dupeDic.Add(part.FacesIndex, (int)amfWriter.BaseStream.Position);
                     *
                     *  indxValueList.Add((int)amfWriter.BaseStream.Position);
                     *
                     *  foreach (var submesh in part.Submeshes)
                     *  {
                     *      var indices = GetTriangleList(part.Indices, submesh.FaceIndex, submesh.FaceCount, renderModel.IndexInfoList[part.FacesIndex].FaceFormat);
                     *      foreach (var index in indices)
                     *      {
                     *          if (part.Vertices.Length > 0xFFFF) amfWriter.Write(index);
                     *          else amfWriter.Write((ushort)index);
                     *      }
                     *  }
                     *
                     * }
                     #endregion
                     #region Submeshes
                     * foreach (var perm in permutations)
                     * {
                     *  var part = renderModel.ModelSections[perm.PieceIndex];
                     *  meshValueList.Add((int)amfWriter.BaseStream.Position);
                     *  int tCount = 0;
                     *  foreach (var mesh in part.Submeshes)
                     *  {
                     *
                     *      int sCount = GetTriangleList(part.Indices, mesh.FaceIndex, mesh.FaceCount, renderModel.IndexInfoList[part.FacesIndex].FaceFormat).Count / 3;
                     *
                     *      amfWriter.Write((short)mesh.ShaderIndex);
                     *      amfWriter.Write(tCount);
                     *      amfWriter.Write(sCount);
                     *
                     *      tCount += sCount;
                     *  }
                     * }
                     #endregion
                     #region Shaders
                     * headerValueList.Add((int)amfWriter.BaseStream.Position);
                     * foreach (var shaderBlock in renderModel.Shaders)
                     * {
                     *  //skip null shaders
                     *  if (shaderBlock.tagID == -1)
                     *  {
                     *      amfWriter.Write("null\0".ToCharArray());
                     *      for (int i = 0; i < 8; i++)
                     *          amfWriter.Write("null\0".ToCharArray());
                     *
                     *      for (int i = 0; i < 4; i++)
                     *          amfWriter.Write(0);
                     *
                     *      amfWriter.Write(Convert.ToByte(false));
                     *      amfWriter.Write(Convert.ToByte(false));
                     *
                     *      continue;
                     *  }
                     *
                     *  var rmshTag = Cache.IndexItems.GetItemByID(shaderBlock.tagID);
                     *  var rmsh = DefinitionsManager.rmsh(Cache, rmshTag);
                     *  string shaderName = rmshTag.Filename.Substring(rmshTag.Filename.LastIndexOf("\\") + 1) + "\0";
                     *  string[] paths = new string[8] { "null\0", "null\0", "null\0", "null\0", "null\0", "null\0", "null\0", "null\0" };
                     *  float[] uTiles = new float[8] { 1, 1, 1, 1, 1, 1, 1, 1 };
                     *  float[] vTiles = new float[8] { 1, 1, 1, 1, 1, 1, 1, 1 };
                     *  int[] tints = new int[4] { -1, -1, -1, -1 };
                     *  bool isTransparent = false;
                     *  bool ccOnly = false;
                     *
                     *  //Halo4 f****d this up
                     *  if (Cache.Version >= DefinitionSet.Halo3Beta && Cache.Version <= DefinitionSet.HaloReachRetail)
                     *  {
                     *      var rmt2Tag = Cache.IndexItems.GetItemByID(rmsh.Properties[0].TemplateTagID);
                     *      var rmt2 = DefinitionsManager.rmt2(Cache, rmt2Tag);
                     *
                     *      for (int i = 0; i < rmt2.UsageBlocks.Count; i++)
                     *      {
                     *          var s = rmt2.UsageBlocks[i].Usage;
                     *          var bitmTag = Cache.IndexItems.GetItemByID(rmsh.Properties[0].ShaderMaps[i].BitmapTagID);
                     *
                     *          switch (s)
                     *          {
                     *              case "base_map":
                     *                  paths[0] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *              case "detail_map":
                     *              case "detail_map_overlay":
                     *                  paths[1] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *              case "change_color_map":
                     *                  paths[2] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *              case "bump_map":
                     *                  paths[3] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *              case "bump_detail_map":
                     *                  paths[4] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *              case "self_illum_map":
                     *                  paths[5] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *              case "specular_map":
                     *                  paths[6] = (bitmTag != null) ? bitmTag.Filename + "\0" : "null\0";
                     *                  break;
                     *          }
                     *      }
                     *
                     *      for (int i = 0; i < rmt2.ArgumentBlocks.Count; i++)
                     *      {
                     *          var s = rmt2.ArgumentBlocks[i].Argument;
                     *
                     *          switch (s)
                     *          {
                     *              //case "env_tint_color":
                     *              //case "fresnel_color":
                     *              case "albedo_color":
                     *                  tints[0] = i;
                     *                  break;
                     *
                     *              case "self_illum_color":
                     *                  tints[1] = i;
                     *                  break;
                     *
                     *              case "specular_tint":
                     *                  tints[2] = i;
                     *                  break;
                     *          }
                     *      }
                     *
                     *      short[] tiles = new short[8] { -1, -1, -1, -1, -1, -1, -1, -1 };
                     *
                     *      foreach (var map in rmsh.Properties[0].ShaderMaps)
                     *      {
                     *          var bitmTag = Cache.IndexItems.GetItemByID(map.BitmapTagID);
                     *
                     *          for (int i = 0; i < 8; i++)
                     *          {
                     *              if (bitmTag.Filename + "\0" != paths[i]) continue;
                     *
                     *              tiles[i] = (short)map.TilingIndex;
                     *          }
                     *      }
                     *
                     *      for (int i = 0; i < 8; i++)
                     *      {
                     *          try
                     *          {
                     *              uTiles[i] = rmsh.Properties[0].Tilings[tiles[i]].UTiling;
                     *              vTiles[i] = rmsh.Properties[0].Tilings[tiles[i]].VTiling;
                     *          }
                     *          catch { }
                     *      }
                     *  }
                     *  else
                     *      try
                     *      {
                     *          paths[0] = Cache.IndexItems.GetItemByID(rmsh.Properties[0].ShaderMaps[0].BitmapTagID).Filename + "\0";
                     *          uTiles[0] = rmsh.Properties[0].Tilings[rmsh.Properties[0].ShaderMaps[0].TilingIndex].UTiling;
                     *          vTiles[0] = rmsh.Properties[0].Tilings[rmsh.Properties[0].ShaderMaps[0].TilingIndex].VTiling;
                     *      }
                     *      catch { }
                     *
                     *  if (rmshTag.ClassCode != "rmsh" && rmshTag.ClassCode != "mat")
                     *  {
                     *      isTransparent = true;
                     *      if (paths[0] == "null\0" && paths[2] != "null\0")
                     *          ccOnly = true;
                     *  }
                     *
                     *  amfWriter.Write(shaderName.ToCharArray());
                     *  for (int i = 0; i < 8; i++)
                     *  {
                     *      amfWriter.Write(paths[i].ToCharArray());
                     *      if (paths[i] != "null\0")
                     *      {
                     *          amfWriter.Write(uTiles[i]);
                     *          amfWriter.Write(vTiles[i]);
                     *      }
                     *  }
                     *
                     *  for (int i = 0; i < 4; i++)
                     *  {
                     *      if (tints[i] == -1)
                     *      {
                     *          amfWriter.Write(0);
                     *          continue;
                     *      }
                     *
                     *      amfWriter.Write((byte)(255f * rmsh.Properties[0].Tilings[tints[i]].UTiling));
                     *      amfWriter.Write((byte)(255f * rmsh.Properties[0].Tilings[tints[i]].VTiling));
                     *      amfWriter.Write((byte)(255f * rmsh.Properties[0].Tilings[tints[i]].Unknown0));
                     *      amfWriter.Write((byte)(255f * rmsh.Properties[0].Tilings[tints[i]].Unknown1));
                     *  }
                     *
                     *  amfWriter.Write(Convert.ToByte(isTransparent));
                     *  amfWriter.Write(Convert.ToByte(ccOnly));
                     * }
                     #endregion
                     #region Write Addresses
                     * for (int i = 0; i < headerAddressList.Count; i++)
                     * {
                     *  amfWriter.BaseStream.Position = headerAddressList[i];
                     *  amfWriter.Write(headerValueList[i]);
                     * }
                     *
                     * for (int i = 0; i < markerAddressList.Count; i++)
                     * {
                     *  amfWriter.BaseStream.Position = markerAddressList[i];
                     *  amfWriter.Write(markerValueList[i]);
                     * }
                     *
                     * for (int i = 0; i < permAddressList.Count; i++)
                     * {
                     *  amfWriter.BaseStream.Position = permAddressList[i];
                     *  amfWriter.Write(permValueList[i]);
                     * }
                     *
                     * for (int i = 0; i < vertAddressList.Count; i++)
                     * {
                     *  amfWriter.BaseStream.Position = vertAddressList[i];
                     *  amfWriter.Write(vertValueList[i]);
                     * }
                     *
                     * for (int i = 0; i < indxAddressList.Count; i++)
                     * {
                     *  amfWriter.BaseStream.Position = indxAddressList[i];
                     *  amfWriter.Write(indxValueList[i]);
                     * }
                     *
                     * for (int i = 0; i < meshAddressList.Count; i++)
                     * {
                     *  amfWriter.BaseStream.Position = meshAddressList[i];
                     *  amfWriter.Write(meshValueList[i]);
                     * }
                     #endregion*/
                }
        }
Example #6
0
        private void ExtractObj(FileInfo modelFile, RenderModel renderModel, Model.Variant modelVariant, RenderGeometryApiResourceDefinition resourceDefinition, Stream resourceStream)
        {
            using (var objFile = new StreamWriter(modelFile.Create()))
            {
                var objExtractor = new ObjExtractor(objFile);

                // Create a (de)compressor from the first compression block
                var vertexCompressor = new VertexCompressor(renderModel.Geometry.Compression[0]);

                if (modelVariant != null)
                {
                    // Extract each region in the variant
                    foreach (var region in modelVariant.Regions)
                    {
                        // Get the corresonding region in the render model tag
                        if (region.RenderModelRegionIndex >= renderModel.Regions.Count)
                        {
                            continue;
                        }

                        var renderModelRegion = renderModel.Regions[region.RenderModelRegionIndex];

                        // Get the corresponding permutation in the render model tag
                        // (Just extract the first permutation for now)
                        if (region.Permutations.Count == 0)
                        {
                            continue;
                        }

                        var permutation = region.Permutations[0];

                        if (permutation.RenderModelPermutationIndex < 0 ||
                            permutation.RenderModelPermutationIndex >= renderModelRegion.Permutations.Count)
                        {
                            continue;
                        }

                        var renderModelPermutation = renderModelRegion.Permutations[permutation.RenderModelPermutationIndex];

                        // Extract each mesh in the permutation
                        var meshIndex       = renderModelPermutation.MeshIndex;
                        var meshCount       = renderModelPermutation.MeshCount;
                        var regionName      = CacheContext.GetString(region.Name) ?? region.Name.ToString();
                        var permutationName = CacheContext.GetString(permutation.Name) ?? permutation.Name.ToString();

                        Console.WriteLine("Extracting {0} mesh(es) for {1}:{2}...", meshCount, regionName, permutationName);

                        for (var i = 0; i < meshCount; i++)
                        {
                            // Create a MeshReader for the mesh and pass it to the obj extractor
                            var meshReader = new MeshReader(CacheContext.Version, renderModel.Geometry.Meshes[meshIndex + i], resourceDefinition);
                            objExtractor.ExtractMesh(meshReader, vertexCompressor, resourceStream);
                        }
                    }
                }
                else
                {
                    // No variant - just extract every mesh
                    Console.WriteLine("Extracting {0} mesh(es)...", renderModel.Geometry.Meshes.Count);

                    foreach (var mesh in renderModel.Geometry.Meshes)
                    {
                        // Create a MeshReader for the mesh and pass it to the obj extractor
                        var meshReader = new MeshReader(CacheContext.Version, mesh, resourceDefinition);
                        objExtractor.ExtractMesh(meshReader, vertexCompressor, resourceStream);
                    }
                }

                objExtractor.Finish();
            }
        }
Example #7
0
        private void ExtractAmf(FileInfo modelFile, RenderModel renderModel, Model.Variant modelVariant)
        {
            using (var amfStream = modelFile.Create())
                using (var amfWriter = new EndianWriter(amfStream))
                {
                    var dupeDic = new Dictionary <int, int>();

                    var indxAddressList = new List <int>();
                    var indxValueList   = new List <int>();

                    var meshAddressList = new List <int>();
                    var meshValueList   = new List <int>();

                    var regions      = new List <RenderModel.Region>();
                    var permutations = new List <RenderModel.Region.Permutation>();

                    foreach (var variantRegion in modelVariant.Regions)
                    {
                        if (variantRegion.RenderModelRegionIndex == -1)
                        {
                            continue;
                        }

                        var region = renderModel.Regions[variantRegion.RenderModelRegionIndex];
                        var variantPermutations = region.Permutations.Where(i => variantRegion.Permutations.Find(j => j.Name == i.Name) != null).ToList();

                        if (variantPermutations.Count == 0)
                        {
                            continue;
                        }

                        if (!regions.Contains(region))
                        {
                            regions.Add(region);
                        }

                        foreach (var variantPermutation in variantPermutations)
                        {
                            if (!permutations.Contains(variantPermutation))
                            {
                                permutations.Add(variantPermutation);
                            }
                        }
                    }

                    var headerAddressList = new List <int>();
                    var headerValueList   = new List <int>();

                    amfWriter.Write("AMF!".ToCharArray());
                    amfWriter.Write(2.0f); //format version
                    amfWriter.Write((Cache.StringTable.GetString(renderModel.Name) + "\0").ToCharArray());

                    amfWriter.Write(renderModel.Nodes.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    amfWriter.Write(renderModel.MarkerGroups.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    amfWriter.Write(regions.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    amfWriter.Write(renderModel.Materials.Count);
                    headerAddressList.Add((int)amfWriter.BaseStream.Position);
                    amfWriter.Write(0);

                    headerValueList.Add((int)amfWriter.BaseStream.Position);

                    foreach (var node in renderModel.Nodes)
                    {
                        amfWriter.Write((Cache.StringTable.GetString(node.Name) + "\0").ToCharArray());
                        amfWriter.Write(node.ParentNode);
                        amfWriter.Write(node.FirstChildNode);
                        amfWriter.Write(node.NextSiblingNode);
                        amfWriter.Write(node.DefaultTranslation.X * 100);
                        amfWriter.Write(node.DefaultTranslation.Y * 100);
                        amfWriter.Write(node.DefaultTranslation.Z * 100);
                        amfWriter.Write(node.DefaultRotation.I);
                        amfWriter.Write(node.DefaultRotation.J);
                        amfWriter.Write(node.DefaultRotation.K);
                        amfWriter.Write(node.DefaultRotation.W);
                    }

                    var markerAddressList = new List <int>();
                    var markerValueList   = new List <int>();

                    headerValueList.Add((int)amfWriter.BaseStream.Position);

                    foreach (var group in renderModel.MarkerGroups)
                    {
                        amfWriter.Write((Cache.StringTable.GetString(group.Name) + "\0").ToCharArray());
                        amfWriter.Write(group.Markers.Count);
                        markerAddressList.Add((int)amfWriter.BaseStream.Position);
                        amfWriter.Write(0);
                    }

                    foreach (var group in renderModel.MarkerGroups)
                    {
                        markerValueList.Add((int)amfWriter.BaseStream.Position);
                        foreach (var marker in group.Markers)
                        {
                            amfWriter.Write((byte)marker.RegionIndex);
                            amfWriter.Write((byte)marker.PermutationIndex);
                            amfWriter.Write((short)marker.NodeIndex);
                            amfWriter.Write(marker.Translation.X * 100);
                            amfWriter.Write(marker.Translation.Y * 100);
                            amfWriter.Write(marker.Translation.Z * 100);
                            amfWriter.Write(marker.Rotation.I);
                            amfWriter.Write(marker.Rotation.J);
                            amfWriter.Write(marker.Rotation.K);
                            amfWriter.Write(marker.Rotation.W);
                        }
                    }

                    var permAddressList = new List <int>();
                    var permValueList   = new List <int>();

                    headerValueList.Add((int)amfWriter.BaseStream.Position);

                    foreach (var variantRegion in modelVariant.Regions)
                    {
                        if (variantRegion.RenderModelRegionIndex == -1)
                        {
                            continue;
                        }

                        var region = renderModel.Regions[variantRegion.RenderModelRegionIndex];
                        var variantPermutations = region.Permutations.Where(i => variantRegion.Permutations.Find(j => j.Name == i.Name) != null).ToList();

                        if (variantPermutations.Count == 0)
                        {
                            continue;
                        }

                        amfWriter.Write((Cache.StringTable.GetString(region.Name) + "\0").ToCharArray());
                        amfWriter.Write(variantPermutations.Count);
                        permAddressList.Add((int)amfWriter.BaseStream.Position);
                        amfWriter.Write(0);
                    }

                    var vertAddressList = new List <int>();
                    var vertValueList   = new List <int>();
                }
        }
        private bool ExtractAMF(Model.Variant variant, string fileName)
        {
            // Load resource caches
            Console.WriteLine("Loading resource caches...");
            var resourceManager = new ResourceDataManager();

            try
            {
                resourceManager.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);
            }
            catch
            {
                Console.WriteLine("Unable to load the resource .dat files.");
                Console.WriteLine("Make sure that they all exist and are valid.");
                return(true);
            }

            // Deserialize the render model tag
            Console.WriteLine("Reading model data...");
            RenderModel renderModel;

            using (var cacheStream = Info.CacheFile.OpenRead())
            {
                var renderModelContext = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, Definition.RenderModel);
                renderModel = Info.Deserializer.Deserialize <RenderModel>(renderModelContext);
            }

            if (renderModel.Geometry.Resource == null)
            {
                Console.WriteLine("Render model does not have a resource associated with it");
                return(true);
            }

            // Deserialize the resource definition
            var resourceContext = new ResourceSerializationContext(renderModel.Geometry.Resource);
            var definition      = Info.Deserializer.Deserialize <RenderGeometryResourceDefinition>(resourceContext);

            using (var resourceStream = new MemoryStream())
            {
                // Extract the resource data
                resourceManager.Extract(renderModel.Geometry.Resource, resourceStream);

                var regionMeshes = new Dictionary <string, Mesh>();

                foreach (var region in variant.Regions)
                {
                    regionMeshes[Info.StringIDs.GetString(region.Name)] = renderModel.Geometry.Meshes[region.RenderModelRegionIndex];
                }

                var headerAddressList = new List <int>();
                var headerValueList   = new List <int>();
                var markerAddressList = new List <int>();
                var markerValueList   = new List <int>();
                var permAddressList   = new List <int>();
                var permValueList     = new List <int>();
                var vertAddressList   = new List <int>();
                var indxAddressList   = new List <int>();
                var meshAddressList   = new List <int>();

                using (var bw = new BinaryWriter(File.Create(fileName)))
                {
                    #region Header
                    bw.Write("AMF!".ToCharArray());
                    bw.Write(2.0f); //format version
                    bw.Write((Info.StringIDs.GetString(renderModel.Name) + "\0").ToCharArray());

                    bw.Write(renderModel.Nodes.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);

                    bw.Write(renderModel.MarkerGroups.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);

                    bw.Write(regionMeshes.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);

                    bw.Write(renderModel.Materials.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);
                    #endregion
                    #region Nodes
                    headerValueList.Add((int)bw.BaseStream.Position);
                    foreach (var node in renderModel.Nodes)
                    {
                        bw.Write((Info.StringIDs.GetString(node.Name) + "\0").ToCharArray());
                        bw.Write((short)node.ParentNode);
                        bw.Write((short)node.FirstChildNode);
                        bw.Write((short)node.NextSiblingNode);
                        bw.Write(node.DefaultTranslation.X * 100);
                        bw.Write(node.DefaultTranslation.Y * 100);
                        bw.Write(node.DefaultTranslation.Z * 100);
                        bw.Write(node.DefaultRotation.X);
                        bw.Write(node.DefaultRotation.Y);
                        bw.Write(node.DefaultRotation.Z);
                        bw.Write(node.DefaultRotation.W);
                    }
                    #endregion
                    #region Marker Groups
                    headerValueList.Add((int)bw.BaseStream.Position);
                    foreach (var group in renderModel.MarkerGroups)
                    {
                        bw.Write((Info.StringIDs.GetString(group.Name) + "\0").ToCharArray());
                        bw.Write(group.Markers.Count);
                        markerAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);
                    }
                    #endregion
                    #region Markers
                    foreach (var group in renderModel.MarkerGroups)
                    {
                        markerValueList.Add((int)bw.BaseStream.Position);
                        foreach (var marker in group.Markers)
                        {
                            bw.Write((byte)marker.RegionIndex);
                            bw.Write((byte)marker.PermutationIndex);
                            bw.Write((short)marker.NodeIndex);
                            bw.Write(marker.Translation.X * 100);
                            bw.Write(marker.Translation.Y * 100);
                            bw.Write(marker.Translation.Z * 100);
                            bw.Write(marker.Rotation.X);
                            bw.Write(marker.Rotation.Y);
                            bw.Write(marker.Rotation.Z);
                            bw.Write(marker.Rotation.W);
                        }
                    }
                    #endregion
                    #region Regions
                    headerValueList.Add((int)bw.BaseStream.Position);
                    foreach (var region in renderModel.Regions)
                    {
                        bw.Write((Info.StringIDs.GetString(region.Name) + "\0").ToCharArray());
                        bw.Write(regionMeshes.Count);
                        permAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);
                    }
                    #endregion
                    #region Permutations
                    foreach (var part in regionMeshes)
                    {
                        permValueList.Add((int)bw.BaseStream.Position);
                        bw.Write((Info.StringIDs.GetString(variant.Name) + "\0").ToCharArray());

                        if (part.Value.Type == VertexType.Rigid)
                        {
                            bw.Write((byte)1);
                        }
                        else if (part.Value.Type == VertexType.Skinned)
                        {
                            bw.Write((byte)2);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }

                        bw.Write((byte)part.Value.RigidNodeIndex);

                        bw.Write(definition.VertexBuffers[part.Value.VertexBuffers[0]].Definition.Count);
                        vertAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);

                        int count = 0;
                        foreach (var submesh in part.Value.SubParts)
                        {
                            count += submesh.IndexCount;
                        }

                        bw.Write(count);
                        indxAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);

                        bw.Write(part.Value.SubParts.Count);
                        meshAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);

                        bw.Write(float.NaN); //no transforms (render_models are pre-transformed)
                    }
                    #endregion
                }
            }

            return(true);
        }