Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

BudRunBun

Members
  • Posts

    96
  • Joined

  • Last visited

Converted

  • Gender
    Male
  • Location
    Russia

Recent Profile Visitors

840 profile views

BudRunBun's Achievements

Stone Miner

Stone Miner (3/8)

0

Reputation

  1. Thank you! I didn't know that Renderer is a singleton, I thought that for every TE there is its own renderer object but this makes much more sense.
  2. Renderer: package com.budrunbun.lavalamp.renderer; import com.budrunbun.lavalamp.LavaLamp; import com.budrunbun.lavalamp.model.BarrelModel; import com.budrunbun.lavalamp.model.OBJModel; import com.budrunbun.lavalamp.model.OBJModelHandler; import com.budrunbun.lavalamp.tileentity.TurretTileEntity; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.sun.javafx.geom.Vec3d; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.entity.LivingEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import javax.annotation.Nonnull; public class TurretRenderer extends TileEntityRenderer<TurretTileEntity> { private static final ResourceLocation TEXTURES = new ResourceLocation(LavaLamp.MOD_ID, "textures/block/colors/gray.png"); private static final ResourceLocation BLACK = new ResourceLocation(LavaLamp.MOD_ID, "textures/block/colors/gray.png"); private Animator animator; private OBJModel sphereQuarter; private final BarrelModel barrel = new BarrelModel(RenderType::getEntitySolid); // Position of the barrel and the sphere quarters is given in the spherical coordinate system (r, theta, phi) // Angles are in degrees: phi - polar angle(around Z-axis), theta - azimuthal angle // r = 10 / 16 as a barrel length private float phi, theta; public TurretRenderer(TileEntityRendererDispatcher rendererDispatcherIn) { super(rendererDispatcherIn); } @Override public void render(@Nonnull TurretTileEntity turret, float partialTicks, @Nonnull MatrixStack matrices, @Nonnull IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn) { if (animator == null) animator = turret.getAnimator(); if (sphereQuarter == null) sphereQuarter = OBJModelHandler.OBJModels.get(new ResourceLocation(LavaLamp.MOD_ID, "models/block/sphere_quarter.obj")); Minecraft.getInstance().getTextureManager().bindTexture(TEXTURES); updateAngles(turret); BlockPos pos = turret.getPos(); World world = renderDispatcher.world; int light = WorldRenderer.getCombinedLight(world, pos.up()); IVertexBuilder buffer = bufferIn.getBuffer(RenderHelper.getOBJModelRenderType(TEXTURES)); if (turret.isOpen()) renderInOperatingMode(matrices, light, buffer); else renderInLoadingMode(matrices, light, buffer); } private void renderInOperatingMode(MatrixStack matrices, int light, IVertexBuilder buffer) { matrices.push(); // first sphere quarter matrices.push(); matrices.translate(0.5, 1, 0.5 - 0.5 / 16); matrices.translate(0, 0, 0.5 / 16); matrices.rotate(Vector3f.YP.rotation(theta)); matrices.translate(0, 0, -0.5 / 16); matrices.scale(0.8f, 0.8f, 0.8f); sphereQuarter.fillBuffer(matrices, buffer, light); matrices.pop(); // second sphere quarter matrices.push(); matrices.translate(0.5, 1, 0.5 + 0.5 / 16); matrices.translate(0, 0, -0.5 / 16); matrices.rotate(Vector3f.YP.rotation(theta + 180)); matrices.translate(0, 0, -0.5 / 16); matrices.scale(0.8f, 0.8f, 0.8f); sphereQuarter.fillBuffer(matrices, buffer, light); matrices.pop(); // barrel matrices.push(); matrices.translate(0.5, 1, 0.5 - 0.5 / 16); matrices.translate(0, 0, 0.5 / 16); matrices.rotate(Vector3f.YP.rotation(theta)); matrices.rotate(Vector3f.ZP.rotation(phi)); matrices.translate(0, 0, -0.5 / 16); barrel.render(matrices, buffer, light, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); matrices.pop(); matrices.pop(); } private void renderInLoadingMode(MatrixStack matrices, int light, IVertexBuilder buffer) { double sphereDelta = animator.getValueForState("SpheresMoveApart"); double barrelY = animator.getValueForState("BarrelMovesUp"); float barrelAngle = (float) animator.getValueForState("BarrelTurnsInPosition"); matrices.push(); // first sphere quarter matrices.push(); matrices.translate(0.5, 1, 0.5 - sphereDelta); matrices.translate(0, 0, sphereDelta); matrices.rotate(Vector3f.YP.rotation(barrelAngle)); matrices.translate(0, 0, -sphereDelta); matrices.scale(0.8f, 0.8f, 0.8f); sphereQuarter.fillBuffer(matrices, buffer, light); matrices.pop(); // second sphere quarter matrices.push(); matrices.translate(0.5, 1, 0.5 + sphereDelta); matrices.translate(0, 0, -sphereDelta); matrices.rotate(Vector3f.YP.rotation(theta + 180)); matrices.translate(0, 0, -sphereDelta); matrices.scale(0.8f, 0.8f, 0.8f); sphereQuarter.fillBuffer(matrices, buffer, light); matrices.pop(); // barrel matrices.push(); matrices.translate(0.5, barrelY, 0.5 - 0.5 / 16); matrices.translate(0, 0, 0.5 / 16); matrices.rotate(Vector3f.YP.rotation(theta)); matrices.rotate(Vector3f.ZP.rotation(barrelAngle)); matrices.translate(0, 0, -0.5 / 16); barrel.render(matrices, buffer, light, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); matrices.pop(); matrices.pop(); } private void updateAngles(TurretTileEntity turret) { LivingEntity target = turret.getTarget(); BlockPos pos = turret.getPos(); if (target != null) { Vec3d vec = new Vec3d( (pos.getX() + 0.5) - target.getPosX(), (pos.getY() + 1) - (target.getPosY() + target.getEyeHeight()), (pos.getZ() + 0.5) - target.getPosZ() ); vec.normalize(); theta = 90 + (float) Math.toDegrees(Math.atan2(vec.x, vec.z)); phi = -90 + (float) Math.toDegrees(vec.dot(new Vec3d(0, 1, 0))); } } } OBJModel: package com.budrunbun.lavalamp.model; import com.budrunbun.lavalamp.renderer.RenderHelper; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import net.minecraft.client.renderer.Matrix3f; import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector4f; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; import java.util.Iterator; import java.util.Spliterator; import java.util.Vector; import java.util.function.Consumer; public class OBJModel implements Iterable<OBJModel.Face> { private final Vector<Face> faces; public OBJModel(Vector<Face> faces) { this.faces = faces; } public void fillBuffer(MatrixStack matrices, IVertexBuilder buffer, int light) { for (Face face : this) { Matrix4f matrix4f = matrices.getLast().getMatrix(); Matrix3f matrix3f = matrices.getLast().getNormal(); Vector3f normal = face.trueNormal; normal.transform(matrix3f); for (int i = 0; i < face.vertices.length; i++) { Vector4f position = new Vector4f(face.vertices[i].getX(), face.vertices[i].getY(), face.vertices[i].getZ(), 1.0F); position.transform(matrix4f); buffer.addVertex( position.getX(), position.getY(), position.getZ(), 1, 1, 1, 1, face.tex[i].x, face.tex[i].y, OverlayTexture.NO_OVERLAY, light, normal.getX(), normal.getY(), normal.getZ() ); } } } public static class Material { public final String name; public Vec3d ambientColour = new Vec3d(0, 0, 0); public ResourceLocation ambientColourMap; public Vec3d diffuseColour = new Vec3d(1, 1, 1); public ResourceLocation diffuseColourMap; public Vec3d specularColour = new Vec3d(0, 0, 0); public float specularHighlight = 0; public ResourceLocation specularColourMap; public float opticalDensity = 1; public int illuminationModel = 2; public float dissolve = 1.0f; public float transparency = 0.0f; public Material(String name) { this.name = name; } } public static class Face { public final Vector3f[] normals; public final Vec2f[] tex; public final Vector3f[] vertices; public final String materialName; public Material material; public final Vector3f trueNormal; public Face(Vector3f[] vertex, Vec2f[] tex, Vector3f[] normal, String materialName) { this.vertices = vertex; this.tex = tex; this.normals = normal; this.materialName = materialName; Vector3f vec1 = new Vector3f(vertices[1].getX() - vertices[0].getX(), vertices[1].getY() - vertices[0].getY(), vertices[1].getZ() - vertices[0].getZ()); Vector3f vec2 = new Vector3f(vertices[2].getX() - vertices[0].getX(), vertices[2].getY() - vertices[0].getY(), vertices[2].getZ() - vertices[0].getZ()); vec1.cross(vec2); RenderHelper.normaliseVector(vec1); this.trueNormal = vec1; } } @Override public Iterator<Face> iterator() { return this.faces.iterator(); } @Override public void forEach(Consumer<? super Face> action) { this.faces.forEach(action); } @Override public Spliterator<Face> spliterator() { return this.faces.spliterator(); } }
  3. If I place two turrets far away from each other and an enemy next to the first one, the first turret will start the animation as intended, but the other turret, which is far away and out of range of the enemy, will open too, then freeze, since there is no enemy nearby. However, as soon as the enemy is dead, turrets start shutting down simultaniously.
  4. I have a turret tile entity class with an animator field(basically just a ticking animation machine) but somehow two different turrets access the same animator object. Why is this happening? How to fix it? Tile entity class: package com.budrunbun.lavalamp.tileentity; import com.budrunbun.lavalamp.renderer.Animator; import com.sun.javafx.geom.Vec3d; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.MobEntity; import net.minecraft.entity.monster.IMob; import net.minecraft.nbt.CompoundNBT; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.MathHelper; import javax.annotation.Nonnull; import java.util.List; import static net.minecraftforge.common.util.Constants.BlockFlags.DEFAULT_AND_RERENDER; public class TurretTileEntity extends TileEntity implements ITickableTileEntity { private long lastShotTime = 0, ticksAfterLosingTarget = 0; private LivingEntity target; private final Animator animator; private static final long ATTACK_COOLDOWN = 5, TARGET_WAITING_TIME = 20; public TurretTileEntity() { super(ModTileEntities.TURRET_TE); animator = new Animator(); animator.add("SpheresMoveApart", 0, 0.5 / 16, 2) .add("BarrelMovesUp", 5.99 / 16.0, 1, 2) .add("BarrelTurnsInPosition", 90, 0, 2); } public boolean isShutDown() { return ticksAfterLosingTarget > TARGET_WAITING_TIME; } public boolean isOpen() { return animator.isFinished() && !animator.isReversed(); } public Animator getAnimator() { return animator; } public LivingEntity getTarget() { return target; } @Override public void tick() { if (target == null) findTarget(); else checkTarget(); if (isOpen()) { if (isShutDown()) animator.reverseAll(); } else { if (target != null && animator.isReversed() || target == null && !animator.isReversed()) animator.reverseAll(); } animator.tick(); } // FIXME: doesn't work private boolean canSee() { return true; } private void shoot() { Vec3d vec = new Vec3d( (pos.getX() + 0.5) - target.getPosX(), (pos.getY() + 1) - (target.getPosY() + target.getEyeHeight()), (pos.getZ() + 0.5) - target.getPosZ() ); // Make vector length equal to 10 / 16 // For some unknown reason it's pointing in the opposite direction // so it's also inverted here vec.mul(-10.0 / 16 / vec.length()); // Bullet shoots out of the end of the barrel BulletEntity bullet = new BulletEntity( world, (getPos().getX() + 0.5) + vec.x, (pos.getY() + 1) + vec.y, (pos.getZ() + 0.5) + vec.z ); double d0 = target.getPosY() + target.getEyeHeight() - (1 + vec.y); double d1 = target.getPosX() - ((getPos().getX() + 0.5) + vec.x); double d2 = d0 - bullet.getPosY(); double d3 = target.getPosZ() - ((getPos().getZ() + 0.5) + vec.z); float f = MathHelper.sqrt(d1 * d1 + d3 * d3) * 0.2F; bullet.shoot(d1, d2 + (double) f, d3, 1.6F, 12.0F); world.addEntity(bullet); } private void findTarget() { List<LivingEntity> entities = world.getEntitiesWithinAABB( MobEntity.class, new AxisAlignedBB( getPos().getX(), getPos().getY(), getPos().getZ(), getPos().getX() + 1, getPos().getY() + 1, getPos().getZ() + 1 ).grow(6), entity -> !entity.isSpectator() && entity instanceof IMob ); for (LivingEntity e : entities) if (canSee()) { target = e; ticksAfterLosingTarget = 0; if (animator.isPaused() || animator.isFinished()) animator.start(); update(); return; } if (isOpen()) ticksAfterLosingTarget++; } private void checkTarget() { if (!target.isAlive() || !canSee()) { target = null; update(); return; } if (world.getGameTime() - lastShotTime > ATTACK_COOLDOWN && isOpen()) { lastShotTime = world.getGameTime(); shoot(); } } @Override public void read(@Nonnull CompoundNBT compound) { super.read(compound); this.animator.deserializeNBT(compound.getCompound("animator")); } @Nonnull @Override public CompoundNBT write(@Nonnull CompoundNBT compound) { super.write(compound); compound.put("animator", animator.serializeNBT()); return compound; } @Nonnull @Override public CompoundNBT getUpdateTag() { CompoundNBT tag = super.getUpdateTag(); this.write(tag); return tag; } @Override public void handleUpdateTag(CompoundNBT tag) { this.read(tag); } @Nonnull @Override public SUpdateTileEntityPacket getUpdatePacket() { return new SUpdateTileEntityPacket(pos, -1, getUpdateTag()); } @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { CompoundNBT tag = pkt.getNbtCompound(); this.handleUpdateTag(tag); update(); } private void update() { this.world.notifyBlockUpdate(this.pos, getBlockState(), getBlockState(), DEFAULT_AND_RERENDER); } } Animator class: package com.budrunbun.lavalamp.renderer; import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.util.math.MathHelper; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.INBTSerializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Animator implements INBTSerializable<CompoundNBT> { private final List<State> states = new ArrayList<>(); private State current; private boolean finished = false, reversed = false, paused = true; private int index; public Animator add(State state) { states.add(state); return this; } public Animator add(String name, double start, double end) { return add(new State(name, start, end)); } public Animator add(String name, double start, double end, double duration /* in seconds */) { return add(new State(name, start, end, duration)); } public void start() { paused = finished = false; current = states.get(0); index = 0; } public void tick() { if (finished || paused) return; if (current.finished) if (index < states.size() - 1) current = states.get(++index); else { finished = true; return; } current.tick(); } public double getValueForState(String name) { for (State s : states) if (s.name.equals(name)) return s.getValue(); throw new IllegalArgumentException("No animation state with name \"" + name + "\""); } public void reverseAll() { for (State s : states) s.reverse(); reversed = !reversed; Collections.reverse(states); start(); } public void resume() { paused = false; } public void pause() { paused = true; } public boolean isPaused() { return paused; } public boolean isFinished() { return finished; } public boolean isReversed() { return reversed; } @Override public CompoundNBT serializeNBT() { ListNBT nbtTagList = new ListNBT(); CompoundNBT nbt = new CompoundNBT(); for (int i = 0; i < states.size(); i++) { CompoundNBT stateTag = new CompoundNBT(); stateTag.putInt("index", i); states.get(i).write(stateTag); nbtTagList.add(stateTag); } nbt.put("states", nbtTagList); nbt.putBoolean("finished", finished); nbt.putBoolean("reversed", reversed); nbt.putBoolean("paused", paused); nbt.putInt("current_index", index); return nbt; } @Override public void deserializeNBT(CompoundNBT nbt) { System.out.println("Deserialize"); ListNBT statesTagList = nbt.getList("states", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < statesTagList.size(); i++) { CompoundNBT itemTags = statesTagList.getCompound(i); int index = itemTags.getInt("index"); State state = new State(); state.read(itemTags); states.set(index, state); } finished = nbt.getBoolean("finished"); reversed = nbt.getBoolean("reversed"); paused = nbt.getBoolean("paused"); index = nbt.getInt("current_index"); current = states.get(index); } public static class State { private double delta = 5E-2; private double start, end, value, prev_value; private boolean finished = false; private String name; public State(String name, double start, double end, double duration /* in seconds */) { this(name, start, end); this.delta = (end - start) / (20 * duration); } public State(String name, double start, double end) { this.name = name; this.start = start; this.end = end; this.value = this.prev_value = start; } private State() { } private void tick() { prev_value = value; value += delta; checkValue(); } private double getValue() { float partialTicks = Minecraft.getInstance().getRenderPartialTicks(); return MathHelper.lerp(partialTicks, this.prev_value, this.value); } private void reverse() { double temp = start; start = end; end = temp; delta *= -1; checkValue(); } private void checkValue() { finished = (delta > 0 && value >= end) || (delta < 0 && value <= end); if (finished) value = prev_value = end; } private void write(CompoundNBT nbt) { nbt.putDouble("delta", delta); nbt.putDouble("start", start); nbt.putDouble("end", end); nbt.putDouble("value", value); nbt.putDouble("prev_value", prev_value); nbt.putBoolean("finished", finished); nbt.putString("name", name); } private void read(CompoundNBT nbt) { delta = nbt.getDouble("delta"); start = nbt.getDouble("start"); end = nbt.getDouble("end"); value = nbt.getDouble("value"); prev_value = nbt.getDouble("prev_value"); finished = nbt.getBoolean("finished"); name = nbt.getString("name"); } } }
  5. Minecraft#shutdown could work but I don't know what you need it for. Also, it does not save the world data, so you need to call World#sendQuittingDisconnectingPacket first.
  6. The correct function, for whose, who need it, is: public static void normaliseVector(Vector3f vector) { float mu = vector.getX() * vector.getX() + vector.getY() * vector.getY() + vector.getZ() * vector.getZ(); vector.mul((float) MathHelper.fastInvSqrt(mu)); }
  7. Problem solved, it was with the Vec3f#normalize method. Because of the incorrect length multiplier resulting vector was not unit. Now it looks like this:
  8. I have a structure, which generates in a world but I want it to be a part of a village. How would I do that?
  9. I have made some progress. I tried loading OBJ model myself(it works fine) and rendering it with triangles, not quads. Now ambient lighning works but diffuse doesn't: colour is changing every frame in random order, i.e the surface keeps flashing even when I stand still and look at it. I believe that problem is connected with normals but I can be wrong. My code: 1) TE renderer: package com.budrunbun.lavalamp.renderer; import com.budrunbun.lavalamp.LavaLamp; import com.budrunbun.lavalamp.model.OBJModel; import com.budrunbun.lavalamp.model.OBJModelHandler; import com.budrunbun.lavalamp.tileentity.TurretTileEntity; import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import javax.annotation.Nonnull; public class TurretRenderer extends TileEntityRenderer<TurretTileEntity> { private static final ResourceLocation TEXTURES = new ResourceLocation(LavaLamp.MOD_ID, "textures/block/colors/gray.png"); private static final RenderType TURRET_RENDER_TYPE = RenderHelper.getOBJModelRenderType(TEXTURES); private OBJModel sphereQuarter; public TurretRenderer(TileEntityRendererDispatcher rendererDispatcherIn) { super(rendererDispatcherIn); } @Override public void render(TurretTileEntity turret, float partialTicks, @Nonnull MatrixStack matrices, @Nonnull IRenderTypeBuffer buffer, int light, int combinedOverlayIn) { BlockPos pos = turret.getPos(); World world = turret.getWorld(); if (sphereQuarter == null) sphereQuarter = OBJModelHandler.OBJModels.get(new ResourceLocation(LavaLamp.MOD_ID, "models/block/sphere_quarter.obj")); matrices.push(); matrices.translate(0, 1, 0); matrices.scale(0.25F, 0.25F, 0.25F); sphereQuarter.render( matrices, buffer.getBuffer(TURRET_RENDER_TYPE), WorldRenderer.getCombinedLight(world, pos.up()), OverlayTexture.NO_OVERLAY, 1, 1, 1, 1 ); matrices.pop(); } } 2) OBJ model: package com.budrunbun.lavalamp.model; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import net.minecraft.client.renderer.Matrix3f; import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector4f; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; import java.util.Iterator; import java.util.Spliterator; import java.util.Vector; import java.util.function.Consumer; public class OBJModel implements Iterable<OBJModel.Face> { private final Vector<Face> faces; public OBJModel(Vector<Face> faces) { this.faces = faces; } public void render(MatrixStack matrices, IVertexBuilder buffer, int light, int lightningOverlay, float red, float green, float blue, float alpha) { Matrix4f matrix4f = matrices.getLast().getMatrix(); Matrix3f matrix3f = matrices.getLast().getNormal(); for (Face face : this.faces) { Vector3f normal = face.normal; normal.transform(matrix3f); for (int i = 0; i < face.vertices.length; i++) { Vector4f position = new Vector4f(face.vertices[i].getX(), face.vertices[i].getY(), face.vertices[i].getZ(), 1); position.transform(matrix4f); buffer.addVertex( position.getX(), position.getY(), position.getZ(), red, green, blue, alpha, face.tex[i].x, face.tex[i].y, lightningOverlay, light, normal.getX(), normal.getY(), normal.getZ() ); } } } public static class Material { public final String name; public Vec3d ambientColour = new Vec3d(0, 0, 0); public ResourceLocation ambientColourMap; public Vec3d diffuseColour = new Vec3d(1, 1, 1); public ResourceLocation diffuseColourMap; public Vec3d specularColour = new Vec3d(0, 0, 0); public float specularHighlight = 0; public ResourceLocation specularColourMap; public float opticalDensity = 1; public int illuminationModel = 2; public float dissolve = 1.0f; public float transparency = 0.0f; public Material(String name) { this.name = name; } } public static class Face { public static final Vec2f NO_TEX = new Vec2f(0, 0); public final Vector3f[] normals; public final Vec2f[] tex; public final Vector3f[] vertices; public final String materialName; public OBJModel.Material material; public final Vector3f normal; public Face(Vector3f[] vertex, Vec2f[] tex, Vector3f[] normal, String materialName) { this.vertices = vertex; this.tex = tex; this.normals = normal; this.materialName = materialName; Vector3f vec1 = new Vector3f(vertices[1].getX() - vertices[0].getX(), vertices[1].getY() - vertices[0].getY(), vertices[1].getZ() - vertices[0].getZ()); Vector3f vec2 = new Vector3f(vertices[2].getX() - vertices[0].getX(), vertices[2].getY() - vertices[0].getY(), vertices[2].getZ() - vertices[0].getZ()); vec1.cross(vec2); vec1.normalize(); this.normal = vec1; } } @Override public Iterator<Face> iterator() { return this.faces.iterator(); } @Override public void forEach(Consumer<? super Face> action) { this.faces.forEach(action); } @Override public Spliterator<Face> spliterator() { return this.faces.spliterator(); } } 3)RenderType: public static RenderType getOBJModelRenderType(ResourceLocation textures) { RenderType.State state = RenderType.State.getBuilder() .texture(new RenderState.TextureState(textures, false, false)) .diffuseLighting(DIFFUSE_LIGHTING_ENABLED) .lightmap(LIGHTMAP_ENABLED) .build(true); return RenderType.makeType( "obj", DefaultVertexFormats.ENTITY, GL11.GL_TRIANGLES, 256, true, false, state ); }
  10. I also checked WorldRenderer#getCombinedLight(world, pos) for my block, for some reason it is always zero
  11. I am stuck. I have looked up #getPackedLightmapCoords but I still don't know how Minecraft calculates the brightness parameter(I suspect via ambient occlusion). Since my model is rendered on top of the block, can I somehow "borrow" color from the top face of it?
  12. I will try to explain it a little bit more verbosely. Basically, your entity is first created on the server and then a message with SSpawnObjectPacket, which is created by Entity#createSpawnPacket, is sent to the client, then magical client-side Mojang algorithms(look at ClientPlayNetHandler#handleSpawnObject), that are hard-coded, just throw your entity away since it's not of vanilla EntityType and don't add it to the ClientWorld lists. So, in effect, you have a strange situation when the entity is operating perfectly fine on the server and client doesn't even know of its existance. The funniest thing about all this is that I was making exactly the same BulletEntity and I spent 2 hours before I found out that the entity is not in the ClientWorld lists.
×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.