예제 #1
0
        public virtual void TesselateShape()
        {
            if (!loaded)
            {
                return;
            }

            shapeFresh = true;
            CompositeShape compositeShape = OverrideCompositeShape != null ? OverrideCompositeShape : entity.Properties.Client.Shape;

            Shape entityShape = OverrideEntityShape != null ? OverrideEntityShape : entity.Properties.Client.LoadedShapeForEntity;

            if (entityShape == null)
            {
                return;
            }

            OnTesselation?.Invoke(ref entityShape, compositeShape.Base.ToString());
            entity.OnTesselation(ref entityShape, compositeShape.Base.ToString());

            defaultTexSource = GetTextureSource();

            TyronThreadPool.QueueTask(() =>
            {
                MeshData meshdata;

                if (entity.Properties.Client.Shape.VoxelizeTexture)
                {
                    int altTexNumber = entity.WatchedAttributes.GetInt("textureIndex", 0);

                    TextureAtlasPosition pos      = defaultTexSource["all"];
                    CompositeTexture[] Alternates = entity.Properties.Client.FirstTexture.Alternates;

                    CompositeTexture tex = altTexNumber == 0 ? entity.Properties.Client.FirstTexture : Alternates[altTexNumber % Alternates.Length];
                    meshdata             = capi.Tesselator.VoxelizeTexture(tex, capi.EntityTextureAtlas.Size, pos);
                    for (int i = 0; i < meshdata.xyz.Length; i += 3)
                    {
                        meshdata.xyz[i]     -= 0.125f;
                        meshdata.xyz[i + 1] -= 0.5f;
                        meshdata.xyz[i + 2] += 0.125f / 2;
                    }
                }
                else
                {
                    try
                    {
                        TesselationMetaData meta = new TesselationMetaData()
                        {
                            quantityElements  = compositeShape.QuantityElements,
                            selectiveElements = compositeShape.SelectiveElements,
                            texSource         = this,
                            withJointIds      = true,
                            withDamageEffect  = true,
                            typeForLogging    = "entity"
                        };

                        capi.Tesselator.TesselateShape(meta, entityShape, out meshdata, new Vec3f(compositeShape.rotateX, compositeShape.rotateY, compositeShape.rotateZ));

                        meshdata.Translate(compositeShape.offsetX, compositeShape.offsetY, compositeShape.offsetZ);
                    }
                    catch (Exception e)
                    {
                        capi.World.Logger.Fatal("Failed tesselating entity {0} with id {1}. Entity will probably be invisible!. The teselator threw {2}", entity.Code, entity.EntityId, e);
                        return;
                    }
                }

                MeshData opaqueMesh = meshdata.Clone().Clear();
                MeshData oitMesh    = meshdata.Clone().Clear();
                opaqueMesh.AddMeshData(meshdata, EnumChunkRenderPass.Opaque);
                oitMesh.AddMeshData(meshdata, EnumChunkRenderPass.Transparent);

                capi.Event.EnqueueMainThreadTask(() =>
                {
                    if (meshRefOpaque != null)
                    {
                        meshRefOpaque.Dispose();
                        meshRefOpaque = null;
                    }
                    if (meshRefOit != null)
                    {
                        meshRefOit.Dispose();
                        meshRefOit = null;
                    }

                    if (capi.IsShuttingDown)
                    {
                        return;
                    }

                    if (opaqueMesh.VerticesCount > 0)
                    {
                        meshRefOpaque = capi.Render.UploadMesh(opaqueMesh);
                    }

                    if (oitMesh.VerticesCount > 0)
                    {
                        meshRefOit = capi.Render.UploadMesh(oitMesh);
                    }
                }, "uploadentitymesh");

                capi.TesselatorManager.ThreadDispose();
            });
        }
예제 #2
0
        private static MeshRef GenerateMesh(ClientMain game, string meshId, ItemStack stack)
        {
            MeshRef         meshRef = null;
            UnloadableShape shape   = new UnloadableShape();

            if (stack.Item.Shape?.Base != null)
            {
                shape.Load(game, new AssetLocationAndSource(stack.Item.Shape.Base));
            }
            if (shape.Textures == null)
            {
                shape.Textures = new Dictionary <string, AssetLocation>();
            }
            if (shape.AttachmentPointsByCode == null)
            {
                shape.AttachmentPointsByCode = new Dictionary <string, AttachmentPoint>();
            }
            Item item = new Item();

            item.Textures = new Dictionary <string, CompositeTexture>();

            foreach (ItemstackAttribute attr in stack.Attributes.GetOrAddTreeAttribute("toolparts").Values)
            {
                ItemStack partstack = attr.GetValue() as ItemStack;
                IToolPart part      = partstack.Item as IToolPart;
                if (part != null)
                {
                    if (part.TinkerProps?.ProvidedTextures == null)
                    {
                        partstack.Item.Textures.ToList().ForEach(kp =>
                        {
                            shape.Textures[kp.Key] = kp.Value.Base;
                            item.Textures[kp.Key]  = kp.Value;
                        });
                        UnloadableShape tmp = new UnloadableShape();
                        if (!tmp.Load(game, new AssetLocationAndSource(partstack.Item.Shape.Base)))
                        {
                            continue;
                        }


                        ShapeElement slot = shape.GetElementByName(part.TinkerProps.PartType);

                        if (slot != null)
                        {
                            slot.Children = slot.Children.Concat(tmp.CloneElements()[0].Children).ToArray();
                        }

                        if (tmp.AttachmentPointsByCode != null)
                        {
                            tmp.AttachmentPointsByCode.ToList().ForEach(kp => shape.AttachmentPointsByCode[kp.Key] = kp.Value);
                        }
                    }
                    else
                    {
                        part.TinkerProps.ProvidedTextures.ToList().ForEach(kp =>
                        {
                            shape.Textures[kp.Key] = kp.Value;
                            item.Textures[kp.Key]  = new CompositeTexture()
                            {
                                Base = kp.Value.Clone()
                            };
                        });
                    }
                }
            }

            ShapeTesselatorManager  manager    = game.GetType().GetField("TesselatorManager", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(game) as ShapeTesselatorManager;
            ItemTextureAtlasManager blockAtlas = game.GetType().GetField("ItemAtlasManager", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(game) as ItemTextureAtlasManager;
            ClientPlatformAbstract  platform   = game.GetType().GetField("Platform", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(game) as ClientPlatformAbstract;

            if (manager != null && blockAtlas != null && platform != null)
            {
                TextureSource       source  = new TextureSource(game, blockAtlas.Size, item);
                var                 field   = manager.Tesselator.GetType().GetField("meta", BindingFlags.Instance | BindingFlags.NonPublic);
                var                 oldMeta = field.GetValue(manager.Tesselator) as TesselationMetaData;
                TesselationMetaData meta    = oldMeta.Clone();
                meta.texSource    = source;
                meta.withJointIds = false;
                MeshData meshData;
                manager.TLTesselator.Value.TesselateShape((Shape)shape, out meshData, new Vec3f(), new Vec3f(), meta);
                meshRef          = platform.UploadMesh(meshData);
                MeshRefs[meshId] = new AccessLifetime <MeshRef>(meshRef);
            }
            return(meshRef);
        }