void RegenMesh() { workItemMeshRef?.Dispose(); workItemMeshRef = null; if (stack == null) { return; } Shape shape; tmpMetal = stack.Collectible.LastCodePart(); if (stack.Collectible.FirstCodePart() == "metalplate") { tmpTextureSource = capi.Tesselator.GetTexSource(capi.World.GetBlock(new AssetLocation("platepile"))); shape = capi.Assets.TryGet("shapes/block/stone/forge/platepile.json").ToObject <Shape>(); } else { tmpTextureSource = capi.Tesselator.GetTexSource(capi.World.GetBlock(new AssetLocation("ingotpile"))); shape = capi.Assets.TryGet("shapes/block/stone/forge/ingotpile.json").ToObject <Shape>(); } workItemTexPos = tmpTextureSource[tmpMetal]; MeshData mesh; capi.Tesselator.TesselateShape("block-fcr", shape, out mesh, this, null, 0, 0, stack.StackSize); mesh.Rgba2 = null; workItemMeshRef = capi.Render.UploadMesh(mesh); }
public ForgeContentsRenderer(BlockPos pos, ICoreClientAPI capi) { this.pos = pos; this.capi = capi; metals = capi.Assets.TryGet("worldproperties/block/metal.json").ToObject <MetalProperty>(); Block block = capi.World.GetBlock(new AssetLocation("forge")); coaltexpos = capi.BlockTextureAtlas.GetPosition(block, "coal"); embertexpos = capi.BlockTextureAtlas.GetPosition(block, "ember"); MeshData emberMesh = QuadMeshUtil.GetCustomQuadHorizontal(3 / 16f, 0, 3 / 16f, 10 / 16f, 10 / 16f, 255, 255, 255, 255); for (int i = 0; i < emberMesh.Uv.Length; i += 2) { emberMesh.Uv[i + 0] = embertexpos.x1 + emberMesh.Uv[i + 0] * 32f / AtlasSize; emberMesh.Uv[i + 1] = embertexpos.y1 + emberMesh.Uv[i + 1] * 32f / AtlasSize; } emberMesh.Flags = new int[] { 128, 128, 128, 128 }; MeshData coalMesh = QuadMeshUtil.GetCustomQuadHorizontal(3 / 16f, 0, 3 / 16f, 10 / 16f, 10 / 16f, 255, 255, 255, 255); for (int i = 0; i < coalMesh.Uv.Length; i += 2) { coalMesh.Uv[i + 0] = coaltexpos.x1 + coalMesh.Uv[i + 0] * 32f / AtlasSize;; coalMesh.Uv[i + 1] = coaltexpos.y1 + coalMesh.Uv[i + 1] * 32f / AtlasSize;; } emberQuadRef = capi.Render.UploadMesh(emberMesh); coalQuadRef = capi.Render.UploadMesh(coalMesh); }
public override void OnBeforeRender(ICoreClientAPI capi, ItemStack itemstack, EnumItemRenderTarget target, ref ItemRenderInfo renderinfo) { string blockMaterialCode = GetBlockMaterialCode(itemstack); if (blockMaterialCode == null) { return; } string key = "pan-filled-" + blockMaterialCode; renderinfo.ModelRef = ObjectCacheUtil.GetOrCreate <MeshRef>(capi, key, () => { AssetLocation shapeloc = new AssetLocation("shapes/block/wood/pan/filled.json"); Shape shape = capi.Assets.TryGet(shapeloc).ToObject <Shape>(); MeshData meshdata; Block block = capi.World.GetBlock(new AssetLocation(blockMaterialCode)); AtlasSize = capi.BlockTextureAtlas.Size; matTexPosition = capi.BlockTextureAtlas.GetPosition(block, "up"); ownTextureSource = capi.Tesselator.GetTexSource(this); capi.Tesselator.TesselateShape("filledpan", shape, out meshdata, this); return(capi.Render.UploadMesh(meshdata)); }); }
public TextureAtlasPosition this[string textureCode] { get { if (contentTextPos == null) { int textureSubId; textureSubId = ObjectCacheUtil.GetOrCreate <int>(capi, "contenttexture-" + contentTexture.ToString() + "-" + contentTexture.Alpha, () => { TextureAtlasPosition texPos; int id = 0; BitmapRef bmp = capi.Assets.TryGet(contentTexture.Base.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi); if (bmp != null) { if (contentTexture.Alpha != 255) { bmp.MulAlpha(contentTexture.Alpha); } capi.BlockTextureAtlas.InsertTexture(bmp, out id, out texPos); bmp.Dispose(); } return(id); }); contentTextPos = capi.BlockTextureAtlas.Positions[textureSubId]; } return(contentTextPos); } }
public TextureAtlasPosition this[string textureCode] { get { TextureAtlasPosition pos = capi.BlockTextureAtlas.GetPosition(block, "up"); return(pos); } }
public FlaskTextureSource(ICoreClientAPI capi, ItemStack forContents, CompositeTexture contentTexture, Block flask) { this.capi = capi; this.forContents = forContents; this.contentTexture = contentTexture; this.corkTextPos = capi.BlockTextureAtlas.GetPosition(flask, "topper"); this.blockTextPos = capi.BlockTextureAtlas.GetPosition(flask, "glass"); this.bracingTextPos = capi.BlockTextureAtlas.GetPosition(flask, "bracing"); }
protected override ITexPositionSource GetTextureSource() { TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId]; int width = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize); int height = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize); capi.EntityTextureAtlas.AllocateTextureSpace(width, height, out skinTextureSubId, out skinTexPos); return(this); }
public TextureAtlasPosition this[string textureCode] { get { AssetLocation textureLoc = null; if (curContProps.Textures != null) { CompositeTexture compTex; if (curContProps.Textures.TryGetValue(textureCode, out compTex)) { textureLoc = compTex.Base; } } if (textureLoc == null && shapeTextures != null) { shapeTextures.TryGetValue(textureCode, out textureLoc); } if (textureLoc != null) { TextureAtlasPosition texPos = capi.BlockTextureAtlas[textureLoc]; if (texPos == null) { BitmapRef bmp = capi.Assets.TryGet(textureLoc.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi); if (bmp != null) { capi.BlockTextureAtlas.InsertTextureCached(textureLoc, bmp, out _, out texPos); bmp.Dispose(); } } return(texPos); } ItemStack content = GetContents(); if (content.Class == EnumItemClass.Item) { TextureAtlasPosition texPos; textureLoc = content.Item.Textures[textureCode].Base; BitmapRef bmp = capi.Assets.TryGet(textureLoc.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi); if (bmp != null) { capi.BlockTextureAtlas.InsertTextureCached(textureLoc, bmp, out _, out texPos); bmp.Dispose(); return(texPos); } } return(contentTexSource[textureCode]); } }
public static MeshData WithTexPos(this MeshData mesh, TextureAtlasPosition texPos) { MeshData meshClone = mesh.Clone(); for (int i = 0; i < meshClone.Uv.Length; i++) { float x = texPos.x2 - texPos.x1; float y = texPos.y2 - texPos.y1; meshClone.Uv[i] = i % 2 == 0 ? (meshClone.Uv[i] * x) + texPos.x1 : (meshClone.Uv[i] * y) + texPos.y1; } return(meshClone); }
public TextureAtlasPosition this[string textureCode] { get { TextureAtlasPosition tp = contentsTexSource["inBucket"]; if (tp != null) { return(tp); } tp = contentsTexSource[forContents.Collectible.Code.Path.ToLowerInvariant()]; return(tp == null ? contentsTexSource["up"] : tp); } }
protected override ITexPositionSource GetTextureSource() { if (!textureSpaceAllocated) { TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId]; int width = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize.Width); int height = (int)((origTexPos.y2 - origTexPos.y1) * AtlasSize.Height); capi.EntityTextureAtlas.AllocateTextureSpace(width, height, out skinTextureSubId, out skinTexPos); textureSpaceAllocated = true; } return(base.GetTextureSource()); }
public TextureAtlasPosition this[string textureCode] { get { AssetLocation texturePath = null; CompositeTexture tex; if (nowTesselatingItem.Textures.TryGetValue(textureCode, out tex)) { texturePath = tex.Baked.BakedName; } else { if (nowTesselatingItem.Textures.TryGetValue("all", out tex)) { texturePath = tex.Baked.BakedName; } else { nowTesselatingShape?.Textures.TryGetValue(textureCode, out texturePath); } } if (texturePath == null) { texturePath = new AssetLocation(textureCode); } TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath]; if (texpos == null) { IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png")); if (texAsset != null) { BitmapRef bmp = texAsset.ToBitmap(capi); capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos); } else { capi.World.Logger.Warning("For render in block " + Block.Code + ", item {0} defined texture {1}, not no such texture found.", nowTesselatingItem.Code, texturePath); } } return(texpos); } }
protected TextureAtlasPosition getOrCreateTexPos(AssetLocation texturePath) { TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath]; if (texpos == null) { IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png")); if (texAsset != null) { BitmapRef bmp = texAsset.ToBitmap(capi); capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos); } else { capi.World.Logger.Warning("For render in block " + Block.Code + ", item {0} defined texture {1}, not no such texture found.", nowTesselatingObj.Code, texturePath); } } return(texpos); }
public TextureAtlasPosition this[string textureCode] { get { if (textureCode == "topper" && corkTextPos != null) { return(corkTextPos); } if (textureCode == "glass" && blockTextPos != null) { return(blockTextPos); } if (textureCode == "bracing" && bracingTextPos != null) { return(bracingTextPos); } if (contentTextPos == null) { int textureSubId; textureSubId = ObjectCacheUtil.GetOrCreate <int>(capi, "contenttexture-" + contentTexture.ToString(), () => { TextureAtlasPosition texPos; int id = 0; BitmapRef bmp = capi.Assets.TryGet(contentTexture.Base.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi); if (bmp != null) { capi.BlockTextureAtlas.InsertTexture(bmp, out id, out texPos); bmp.Dispose(); } return(id); }); contentTextPos = capi.BlockTextureAtlas.Positions[textureSubId]; } return(contentTextPos); } }
public TextureAtlasPosition this[string textureCode] { get { AssetLocation texturePath = crustTextureLoc; if (textureCode == "filling") { texturePath = fillingTextureLoc; } if (textureCode == "topcrust") { texturePath = topCrustTextureLoc; } if (texturePath == null) { capi.World.Logger.Warning("Missing texture path for pie mesh texture code {0}, seems like a missing texture definition or invalid pie block.", textureCode); return(capi.BlockTextureAtlas.UnknownTexturePosition); } TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath]; if (texpos == null) { IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png")); if (texAsset != null) { BitmapRef bmp = texAsset.ToBitmap(capi); capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos); } else { capi.World.Logger.Warning("Pie mesh texture {1} not found.", nowTesselatingBlock.Code, texturePath); texpos = capi.BlockTextureAtlas.UnknownTexturePosition; } } return(texpos); } }
public TextureAtlasPosition this[string textureCode] { get { if (nowTeselatingLabel != null) { return(labelTexturePos); } TextureAtlasPosition pos = tmpTextureSource[curType + "-" + textureCode]; if (pos == null) { pos = tmpTextureSource[textureCode]; } if (pos == null) { pos = (api as ICoreClientAPI).BlockTextureAtlas.UnknownTexturePosition; } return(pos); } }
public MeshData GenLabelMesh(ICoreClientAPI capi, string label, TextureAtlasPosition texPos, bool editableVariant, Vec3f rotation = null) { Props.Labels.TryGetValue(label, out var labelProps); if (Props == null) { throw new ArgumentException("No label props found for this label"); } AssetLocation shapeloc = (editableVariant ? labelProps.EditableShape : labelProps.Shape).Base.Clone().WithPathAppendixOnce(".json").WithPathPrefixOnce("shapes/"); Shape shape = capi.Assets.TryGet(shapeloc)?.ToObject <Shape>(); var rot = rotation == null ? new Vec3f(labelProps.Shape.rotateX, labelProps.Shape.rotateY, labelProps.Shape.rotateZ) : rotation; nowTeselatingLabel = labelProps; labelTexturePos = texPos; capi.Tesselator.TesselateShape("cratelabel", shape, out var meshLabel, this, rot); nowTeselatingLabel = null; return(meshLabel); }
protected TextureAtlasPosition getOrCreateTexPos(AssetLocation texturePath) { var capi = api as ICoreClientAPI; TextureAtlasPosition texpos = curAtlas[texturePath]; if (texpos == null) { IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png")); if (texAsset != null) { BitmapRef bmp = texAsset.ToBitmap(capi); curAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos, 0.1f); } else { capi.World.Logger.Warning("Item {0} defined texture {1}, not no such texture found.", Code, texturePath); } } return(texpos); }
protected override ITexPositionSource GetTextureSource() { if (!textureSpaceAllocated) { TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId]; string skinBaseTextureKey = entity.Properties.Attributes?["skinBaseTextureKey"].AsString(); if (skinBaseTextureKey != null) { origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.Textures[skinBaseTextureKey].Baked.TextureSubId]; } int width = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize.Width); int height = (int)((origTexPos.y2 - origTexPos.y1) * AtlasSize.Height); capi.EntityTextureAtlas.AllocateTextureSpace(width, height, out skinTextureSubId, out skinTexPos); textureSpaceAllocated = true; } return(base.GetTextureSource()); }
public override void Initialize(ICoreAPI api) { base.Initialize(api); if (api.Side == EnumAppSide.Client) { ICoreClientAPI capi = api as ICoreClientAPI; Block ownBlock = api.World.BlockAccessor.GetBlock(Pos); // Loads the mesh from a model created by VS Model Creator, but you could just as well create a mesh in code, e.g. via QuadMeshUtil.GetCustomQuad(); Shape shape = capi.Assets.TryGet(new AssetLocation("customshapeblock", "shapes/customshapes/plane.json")).ToObject <Shape>(); texPosition = capi.BlockTextureAtlas.GetPosition(ownBlock, "north"); capi.Tesselator.TesselateShape("customshape", shape, out plane, this); // Alternatively you can also use the block itself as texture souce and not implement ITexPositionSource //capi.Tesselator.TesselateShape(ownBlock, shape, out plane); // Move the model up by half a block. Alternatively move it up by half a block in the VSMC model plane.Translate(0, 0.5f, 0); } }
public TFForgeContentsRenderer(BlockPos pos, ICoreClientAPI capi) { this.pos = pos; this.capi = capi; Block block = capi.World.GetBlock(new AssetLocation("temporalengineering:tfforge")); hetexpos = capi.BlockTextureAtlas.GetPosition(block, "iron"); MeshData heMesh; Shape ovshape = capi.Assets.TryGet(new AssetLocation("temporalengineering:shapes/block/tfforge/heating_element.json")).ToObject <Shape>(); capi.Tesselator.TesselateShape(block, ovshape, out heMesh); for (int i = 0; i < heMesh.Uv.Length; i += 2) { heMesh.Uv[i + 0] = hetexpos.x1 + heMesh.Uv[i + 0] * 32f / AtlasSize.Width; heMesh.Uv[i + 1] = hetexpos.y1 + heMesh.Uv[i + 1] * 32f / AtlasSize.Height; } heQuadRef = capi.Render.UploadMesh(heMesh); }
private MeshData getsimpleVoxelMesh() { Block wireblock = capi.World.GetBlock(new AssetLocation("signals:blockwire")); TextureAtlasPosition tpos = capi.BlockTextureAtlas.GetPosition(wireblock, wireblock.Textures.First().Key); texId = tpos.atlasTextureId; //We first generate a mesh for a single voxel MeshData singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); singleVoxelMesh.Rgba = new byte[6 * 4 * 4].Fill((byte)255); CubeMeshUtil.SetXyzFacesAndPacketNormals(singleVoxelMesh); float subPixelPaddingx = capi.BlockTextureAtlas.SubPixelPaddingX; float subPixelPaddingy = capi.BlockTextureAtlas.SubPixelPaddingY; for (int i = 0; i < singleVoxelMesh.Uv.Length; i++) { if (i % 2 > 0) { singleVoxelMesh.Uv[i] = tpos.y1 + singleVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Height - subPixelPaddingy; } else { singleVoxelMesh.Uv[i] = tpos.x1 + singleVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Width - subPixelPaddingx; } } singleVoxelMesh.XyzFaces = (byte[])CubeMeshUtil.CubeFaceIndices.Clone(); singleVoxelMesh.XyzFacesCount = 6; singleVoxelMesh.ClimateColorMapIds = new byte[6].Fill((byte)0); singleVoxelMesh.SeasonColorMapIds = new byte[6].Fill((byte)0); singleVoxelMesh.ColorMapIdsCount = 6; singleVoxelMesh.RenderPasses = new short[singleVoxelMesh.VerticesCount / 4].Fill((short)0); singleVoxelMesh.RenderPassCount = singleVoxelMesh.VerticesCount / 4; return(singleVoxelMesh); }
private void Essr_OnReloadSkin(LoadedTexture atlas, TextureAtlasPosition skinTexPos) { ICoreClientAPI capi = entity.World.Api as ICoreClientAPI; foreach (var val in AppliedSkinParts) { SkinnablePart part = AvailableSkinPartsByCode[val.PartCode]; if (part.Type != EnumSkinnableType.Texture) { continue; } if (part.TextureTarget != null && part.TextureTarget != "seraph") { continue; } LoadedTexture texture = new LoadedTexture(capi); capi.Render.GetOrLoadTexture(val.Texture.Clone().WithPathAppendixOnce(".png"), ref texture); int posx = part.TextureRenderTo.X; int posy = part.TextureRenderTo.Y; capi.EntityTextureAtlas.RenderTextureIntoAtlas( texture, 0, 0, texture.Width, texture.Height, skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width + posx, skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height + posy ); } }
public void RegenMesh(ItemStack ingot, bool[,,] Voxels, SmithingRecipe recipeToOutline) { if (workItemMeshRef != null) { api.Render.DeleteMesh(workItemMeshRef); workItemMeshRef = null; } if (ingot == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline); } this.ingot = ingot; MeshData workItemMesh = new MeshData(24, 36, false); TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("ingotpile")), ingot.Collectible.LastCodePart()); MeshData voxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); texId = tpos.atlasTextureId; for (int i = 0; i < voxelMesh.Uv.Length; i++) { voxelMesh.Uv[i] = (i % 2 > 0 ? tpos.y1 : tpos.x1) + voxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size; } voxelMesh.XyzFaces = (int[])CubeMeshUtil.CubeFaceIndices.Clone(); voxelMesh.XyzFacesCount = 6; voxelMesh.Tints = new int[6]; voxelMesh.Flags = new int[24]; voxelMesh.TintsCount = 6; for (int i = 0; i < voxelMesh.Rgba.Length; i++) { voxelMesh.Rgba[i] = 255; } voxelMesh.Rgba2 = voxelMesh.Rgba; MeshData voxelMeshOffset = voxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int y = 10; y < 16; y++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, y, z]) { continue; } float px = x / 16f; float py = y / 16f; float pz = z / 16f; for (int i = 0; i < voxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + voxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = py + voxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + voxelMesh.xyz[i + 2]; } float offsetX = (px * 32f) / api.BlockTextureAtlas.Size; float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size; for (int i = 0; i < voxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = voxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = voxelMesh.Uv[i + 1] + offsetZ; } workItemMesh.AddMeshData(voxelMeshOffset); } } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
static MeshData genCube(int voxelX, int voxelY, int voxelZ, int width, int height, int length, ICoreClientAPI capi, ITexPositionSource texSource, float subPixelPadding, int renderpass, int renderFlags) { MeshData mesh = CubeMeshUtil.GetCube( width / 32f, height / 32f, length / 32f, new Vec3f(voxelX / 16f, voxelY / 16f, voxelZ / 16f) ); float[] sideShadings = CubeMeshUtil.DefaultBlockSideShadingsByFacing; for (int i = 0; i < mesh.Rgba.Length; i += 4) { int faceIndex = i / 4 / 4; // 4 rgba per vertex, 4 vertices per face byte b = (byte)(255 * sideShadings[faceIndex]); mesh.Rgba[i + 0] = mesh.Rgba[i + 1] = mesh.Rgba[i + 2] = b; } mesh.Flags = new int[mesh.VerticesCount]; mesh.Flags.Fill(renderFlags); mesh.RenderPasses = new int[mesh.VerticesCount / 4]; mesh.RenderPassCount = mesh.VerticesCount / 4; for (int i = 0; i < mesh.RenderPassCount; i++) { mesh.RenderPasses[i] = renderpass; } mesh.Tints = new int[mesh.VerticesCount / 4]; mesh.TintsCount = mesh.VerticesCount / 4; mesh.XyzFaces = new int[mesh.VerticesCount / 4]; mesh.XyzFacesCount = mesh.VerticesCount / 4; int k = 0; for (int i = 0; i < 6; i++) { mesh.XyzFaces[i] = i; BlockFacing facing = BlockFacing.ALLFACES[i]; bool isOutside = ( (facing == BlockFacing.NORTH && voxelZ == 0) || (facing == BlockFacing.EAST && voxelX + width == 16) || (facing == BlockFacing.SOUTH && voxelZ + length == 16) || (facing == BlockFacing.WEST && voxelX == 0) || (facing == BlockFacing.UP && voxelY + height == 16) || (facing == BlockFacing.DOWN && voxelY == 0) ) ; TextureAtlasPosition tpos = isOutside ? texSource[facing.Code] : texSource["inside-" + facing.Code]; if (tpos == null) { tpos = texSource[facing.Code]; } for (int j = 0; j < 2 * 4; j++) { mesh.Uv[k] = (j % 2 > 0 ? tpos.y1 : tpos.x1) + mesh.Uv[k] * 32f / texSource.AtlasSize - subPixelPadding; k++; } } return(mesh); }
public static void SetUv(this MeshData mesh, TextureAtlasPosition texPos) => mesh.SetUv(new float[] { texPos.x1, texPos.y1, texPos.x2, texPos.y1, texPos.x2, texPos.y2, texPos.x1, texPos.y2 });
public override void reloadSkin() { if (skinTexPos == null) { GetTextureSource(); } TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId]; LoadedTexture entityAtlas = new LoadedTexture(null) { TextureId = origTexPos.atlasTextureId, Width = capi.EntityTextureAtlas.Size.Width, Height = capi.EntityTextureAtlas.Size.Height }; capi.Render.GlToggleBlend(true, EnumBlendMode.Overlay); string componentPath = "characters:textures/entity/skin/"; string[] skinParts = Enum.GetNames(typeof(EnumSkinPart)); for (int x = 0; x < skinParts.Length; x++) { AssetLocation componentLoc; string skinProperty = skinParts[x]; float alphaTest = 0.005f; if (skinProperty == "hairtype" || skinProperty == "facialhair") { if (entity.WatchedAttributes.GetString(skinProperty, "none") == "none") { continue; } } switch (skinProperty) { case "skincolor": componentLoc = new AssetLocation( componentPath + "skins/" + entity.WatchedAttributes.GetString("sex", "male") + "/" + entity.WatchedAttributes.GetString("skincolor", "tan") + ".png" ); alphaTest = -1f; break; case "eyecolor": componentLoc = new AssetLocation( componentPath + "eyes/" + entity.WatchedAttributes.GetString("eyecolor", "brown") + ".png" ); break; case "facialhair": componentLoc = new AssetLocation( componentPath + "facialhairs/" + entity.WatchedAttributes.GetString("facialhair", "full") + "-" + entity.WatchedAttributes.GetString("haircolor", "brown") + ".png" ); break; case "hairtype": componentLoc = new AssetLocation( componentPath + "hairs/" + entity.WatchedAttributes.GetString("hairtype", "m") + "-" + entity.WatchedAttributes.GetString("haircolor", "brown") + ".png" ); break; default: componentLoc = new AssetLocation( componentPath + "hairs/" + entity.WatchedAttributes.GetString("hairtype", "m") + "-" + entity.WatchedAttributes.GetString("haircolor", "brown") + ".png" ); break; } LoadedTexture componentTexture = new LoadedTexture(capi); BitmapRef bitMap = capi.Assets.Get(componentLoc).ToBitmap(capi); capi.Render.GetOrLoadTexture(componentLoc, bitMap, ref componentTexture); capi.Render.GlToggleBlend(false); capi.EntityTextureAtlas.RenderTextureIntoAtlas( componentTexture, 0, 0, 128, 128, skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width, skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height, alphaTest ); capi.Render.GlToggleBlend(true, EnumBlendMode.Overlay); } // Standard int[] renderOrder = new int[] { (int)EnumCharacterDressType.LowerBody, (int)EnumCharacterDressType.Foot, (int)EnumCharacterDressType.UpperBody, (int)EnumCharacterDressType.UpperBodyOver, (int)EnumCharacterDressType.Waist, (int)EnumCharacterDressType.Shoulder, (int)EnumCharacterDressType.Emblem, (int)EnumCharacterDressType.Neck, (int)EnumCharacterDressType.Head, (int)EnumCharacterDressType.Hand, (int)EnumCharacterDressType.Arm, (int)EnumCharacterDressType.Face }; if (gearInv == null && (eagent != null && eagent.GearInventory != null)) { eagent.GearInventory.SlotModified += gearSlotModified; gearInv = eagent.GearInventory; } if (gearInv == null) { return; } for (int i = 0; i < renderOrder.Length; i++) { int slotid = renderOrder[i]; if (gearInv[slotid] == null) { continue; } ItemStack stack = gearInv[slotid].Itemstack; if (stack == null) { continue; } int itemTextureSubId = stack.Item.FirstTexture.Baked.TextureSubId; TextureAtlasPosition itemTexPos = capi.ItemTextureAtlas.Positions[itemTextureSubId]; LoadedTexture itemAtlas = new LoadedTexture(null) { TextureId = itemTexPos.atlasTextureId, Width = capi.ItemTextureAtlas.Size.Width, Height = capi.ItemTextureAtlas.Size.Height }; capi.EntityTextureAtlas.RenderTextureIntoAtlas( itemAtlas, itemTexPos.x1 * capi.ItemTextureAtlas.Size.Width, itemTexPos.y1 * capi.ItemTextureAtlas.Size.Height, (itemTexPos.x2 - itemTexPos.x1) * capi.ItemTextureAtlas.Size.Width, (itemTexPos.y2 - itemTexPos.y1) * capi.ItemTextureAtlas.Size.Height, skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width, skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height ); } capi.Render.GlToggleBlend(true); capi.Render.BindTexture2d(skinTexPos.atlasTextureId); capi.Render.GlGenerateTex2DMipmaps(); }
public override void OnLoaded(ICoreAPI api) { paintableOnBlockMaterials = new EnumBlockMaterial[onmaterialsStrTmp.Length]; for (int i = 0; i < onmaterialsStrTmp.Length; i++) { if (onmaterialsStrTmp[i] == null) { continue; } try { paintableOnBlockMaterials[i] = (EnumBlockMaterial)Enum.Parse(typeof(EnumBlockMaterial), onmaterialsStrTmp[i]); } catch (Exception) { api.Logger.Warning("ArtPigment behavior for collectible {0}, paintable on material {1} is not a valid block material, will default to stone", collObj.Code, onmaterialsStrTmp[i]); paintableOnBlockMaterials[i] = EnumBlockMaterial.Stone; } } onmaterialsStrTmp = null; var capi = api as ICoreClientAPI; foreach (var loc in decorCodesTmp) { if (loc.Path.Contains("*")) { Block[] blocks = api.World.SearchBlocks(loc); foreach (var block in blocks) { decorBlocks.Add(block); //Console.WriteLine("\"/bir remapq " + block.Code.ToShortString() + " drawnart"+block.Variant["material"]+"-1-" + block.Variant["row"] +"-" + block.Variant["col"] + " force\","); } if (blocks.Length == 0) { api.Logger.Warning("ArtPigment behavior for collectible {0}, decor {1}, no such block using this wildcard found", collObj.Code, loc); } } else { Block block = api.World.GetBlock(loc); if (block == null) { api.Logger.Warning("ArtPigment behavior for collectible {0}, decor {1} is not a loaded block", collObj.Code, loc); } else { decorBlocks.Add(block); } } } if (api.Side == EnumAppSide.Client) { if (decorBlocks.Count > 0) { BakedCompositeTexture tex = decorBlocks[0].Textures["up"].Baked; texPos = capi.BlockTextureAtlas.Positions[tex.TextureSubId]; } else { texPos = capi.BlockTextureAtlas.UnknownTexturePosition; } } AssetLocation blockCode = collObj.Code; toolModes = new SkillItem[decorBlocks.Count]; for (int i = 0; i < toolModes.Length; i++) { toolModes[i] = new SkillItem() { Code = blockCode.CopyWithPath("art" + i), // Unique code, it doesn't really matter what it is Linebreak = i % GlobalConstants.CaveArtColsPerRow == 0, Name = "", // No name - alternatively each icon could be given a name? But discussed in meeting on 6/6/21 and decided it is better for players to assign their own meanings to the icons Data = decorBlocks[i], RenderHandler = (AssetLocation code, float dt, double atPosX, double atPosY) => { float wdt = (float)GuiElement.scaled(GuiElementPassiveItemSlot.unscaledSlotSize); string id = code.Path.Substring(3); capi.Render.Render2DTexture(meshes[int.Parse(id)], texPos.atlasTextureId, (float)atPosX, (float)atPosY, wdt, wdt); } }; } if (capi != null) { meshes = new MeshRef[decorBlocks.Count]; for (int i = 0; i < meshes.Length; i++) { MeshData mesh = genMesh(i); meshes[i] = capi.Render.UploadMesh(mesh); } } }
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(); }); }
protected void RenderHeldItem(float dt, bool isShadowPass, bool right) { IRenderAPI rapi = capi.Render; ItemSlot slot = right ? eagent?.RightHandItemSlot : eagent?.LeftHandItemSlot; ItemStack stack = slot?.Itemstack; AttachmentPointAndPose apap = entity.AnimManager.Animator.GetAttachmentPointPose(right ? "RightHand" : "LeftHand"); if (apap == null || stack == null) { return; } AttachmentPoint ap = apap.AttachPoint; ItemRenderInfo renderInfo = rapi.GetItemStackRenderInfo(slot, right ? EnumItemRenderTarget.HandTp : EnumItemRenderTarget.HandTpOff); IStandardShaderProgram prog = null; if (renderInfo?.Transform == null) { return; // Happens with unknown items/blocks } ItemModelMat .Set(ModelMat) .Mul(apap.AnimModelMatrix) .Translate(renderInfo.Transform.Origin.X, renderInfo.Transform.Origin.Y, renderInfo.Transform.Origin.Z) .Scale(renderInfo.Transform.ScaleXYZ.X, renderInfo.Transform.ScaleXYZ.Y, renderInfo.Transform.ScaleXYZ.Z) .Translate(ap.PosX / 16f + renderInfo.Transform.Translation.X, ap.PosY / 16f + renderInfo.Transform.Translation.Y, ap.PosZ / 16f + renderInfo.Transform.Translation.Z) .RotateX((float)(ap.RotationX + renderInfo.Transform.Rotation.X) * GameMath.DEG2RAD) .RotateY((float)(ap.RotationY + renderInfo.Transform.Rotation.Y) * GameMath.DEG2RAD) .RotateZ((float)(ap.RotationZ + renderInfo.Transform.Rotation.Z) * GameMath.DEG2RAD) .Translate(-(renderInfo.Transform.Origin.X), -(renderInfo.Transform.Origin.Y), -(renderInfo.Transform.Origin.Z)) ; if (isShadowPass) { rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); float[] mvpMat = Mat4f.Mul(ItemModelMat.Values, capi.Render.CurrentModelviewMatrix, ItemModelMat.Values); Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat); capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat); capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f()); } else { prog = rapi.StandardShader; prog.Use(); prog.DontWarpVertices = 0; prog.AddRenderFlags = 0; prog.NormalShaded = 1; prog.Tex2D = renderInfo.TextureId; prog.RgbaTint = ColorUtil.WhiteArgbVec; prog.AlphaTest = renderInfo.AlphaTest; prog.DamageEffect = renderInfo.DamageEffect; prog.OverlayOpacity = renderInfo.OverlayOpacity; if (renderInfo.OverlayTexture != null && renderInfo.OverlayOpacity > 0) { prog.Tex2dOverlay2D = renderInfo.OverlayTexture.TextureId; prog.OverlayTextureSize = new Vec2f(renderInfo.OverlayTexture.Width, renderInfo.OverlayTexture.Height); prog.BaseTextureSize = new Vec2f(renderInfo.TextureSize.Width, renderInfo.TextureSize.Height); TextureAtlasPosition texPos = rapi.GetTextureAtlasPosition(stack); prog.BaseUvOrigin = new Vec2f(texPos.x1, texPos.y1); } int temp = (int)stack.Collectible.GetTemperature(capi.World, stack); float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp); /*lightrgbs[0] += glowColor[0]; * lightrgbs[1] += glowColor[1]; * lightrgbs[2] += glowColor[2];*/ var gi = GameMath.Clamp((temp - 500) / 3, 0, 255); prog.ExtraGlow = gi; prog.RgbaAmbientIn = rapi.AmbientColor; prog.RgbaLightIn = lightrgbs; prog.RgbaGlowIn = new Vec4f(glowColor[0], glowColor[1], glowColor[2], gi / 255f); prog.RgbaFogIn = rapi.FogColor; prog.FogMinIn = rapi.FogMin; prog.FogDensityIn = rapi.FogDensity; prog.NormalShaded = renderInfo.NormalShaded ? 1 : 0; prog.ProjectionMatrix = rapi.CurrentProjectionMatrix; prog.ViewMatrix = rapi.CameraMatrixOriginf; prog.ModelMatrix = ItemModelMat.Values; } if (!renderInfo.CullFaces) { rapi.GlDisableCullFace(); } rapi.RenderMesh(renderInfo.ModelRef); if (!renderInfo.CullFaces) { rapi.GlEnableCullFace(); } if (!isShadowPass) { prog.DamageEffect = 0; } if (!isShadowPass) { prog.Stop(); AdvancedParticleProperties[] ParticleProperties = stack.Collectible?.ParticleProperties; if (stack.Collectible != null && !capi.IsGamePaused) { Vec4f pos = ItemModelMat.TransformVector(new Vec4f(stack.Collectible.TopMiddlePos.X, stack.Collectible.TopMiddlePos.Y, stack.Collectible.TopMiddlePos.Z, 1)); EntityPlayer entityPlayer = capi.World.Player.Entity; accum += dt; if (ParticleProperties != null && ParticleProperties.Length > 0 && accum > 0.025f) { accum = accum % 0.025f; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + entity.Pos.X + -(entity.Pos.X - entityPlayer.CameraPos.X); bps.basePos.Y = pos.Y + entity.Pos.Y + -(entity.Pos.Y - entityPlayer.CameraPos.Y); bps.basePos.Z = pos.Z + entity.Pos.Z + -(entity.Pos.Z - entityPlayer.CameraPos.Z); eagent.World.SpawnParticles(bps); } } } } }