Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package com.portofino.polygontrainmod.client.renderer;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.portofino.polygontrainmod.PolygonTrainMod;
import com.portofino.polygontrainmod.entity.CarEntity;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix4f;
import org.joml.Vector3f;

@OnlyIn(Dist.CLIENT)
public class CarRenderer extends EntityRenderer<CarEntity> {

public static final ResourceLocation TEXTURE
= ResourceLocation.fromNamespaceAndPath(PolygonTrainMod.MODID, "textures/block/test_block");
public static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(PolygonTrainMod.MODID, "textures/uv-checker-1024px.png");

public CarRenderer(EntityRendererProvider.Context context) {
super(context);
Expand All @@ -25,14 +31,38 @@ public ResourceLocation getTextureLocation(@NotNull CarEntity entity) {
}

@Override
public void render(
CarEntity entity,
float entityYaw,
float partialTick,
PoseStack posestack,
MultiBufferSource buffer,
int packedLight
) {
super.render(entity, entityYaw, partialTick, posestack, buffer, packedLight);
public void render(@NotNull CarEntity entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) {
poseStack.pushPose();

VertexConsumer buffer = bufferSource.getBuffer(RenderType.entityTranslucentCull(TEXTURE));

Matrix4f matrix = poseStack.last().pose();

buildQuad(buffer, matrix, packedLight);

poseStack.popPose();
super.render(entity, entityYaw, partialTick, poseStack, bufferSource, packedLight);
}

private void buildQuad(VertexConsumer buffer, Matrix4f matrix, int light) {
Vector3f testNormalVector = new Vector3f(1, 0, 1).normalize();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

testNormalVector は定数なので、renderメソッドが呼ばれるたびにインスタンス化と計算を行うのは非効率です。static finalなフィールドとしてクラスレベルで宣言することをお勧めします。

例:

private static final Vector3f SMOOTH_NORMAL = new Vector3f(1, 0, 1).normalize();

そして、buildQuadメソッド内でこの定数を直接使用します。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀


float x = testNormalVector.x;
float y = testNormalVector.y;
float z = testNormalVector.z;

// ポリゴン1
buffer.addVertex(matrix, 0, 1, 0).setColor(255, 255, 255, 255).setUv(0, 0).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(0, 0, 1);
buffer.addVertex(matrix, 0, 0, 0).setColor(255, 255, 255, 255).setUv(0, 1).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(0, 0, 1);
buffer.addVertex(matrix, 1, 0, 0).setColor(255, 255, 255, 255).setUv(1, 1).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(x, y, z);
buffer.addVertex(matrix, 1, 1, 0).setColor(255, 255, 255, 255).setUv(1, 0).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(x, y, z);

// 両ポリゴンの重なる2頂点について、ナナメ45度の方向の法線ベクトルを追加して、簡易的なスムースシェーディング処理を行う

// ポリゴン2
buffer.addVertex(matrix, 1, 1, 0).setColor(255, 255, 255, 255).setUv(0, 0).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(x, y, z);
buffer.addVertex(matrix, 1, 0, 0).setColor(255, 255, 255, 255).setUv(0, 1).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(x, y, z);
buffer.addVertex(matrix, 1, 0, -1).setColor(255, 255, 255, 255).setUv(1, 1).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(1, 0, 0);
buffer.addVertex(matrix, 1, 1, -1).setColor(255, 255, 255, 255).setUv(1, 0).setOverlay(OverlayTexture.NO_OVERLAY).setLight(light).setNormal(1, 0, 0);
}
}
}
28 changes: 14 additions & 14 deletions src/main/java/com/portofino/polygontrainmod/entity/CarEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;

// Entityについて
// Entityは、BlockやItemと異なり、1つの実体に対して必ず1つのインスタンスを持つ。それによって、より多くの状態と処理を実装できる。
/**
* 自動車Entityクラス<br>
* <strong>Entityについて</strong><br>
* Entityは、BlockやItemと異なり、1つの実体に対して必ず1つのインスタンスを持つ。それによって、より多くの状態と処理を実装できる。
* 自動車Entityクラス
*/
public class CarEntity extends Entity {
// private static final EntityDataAccessor<Float> DATA_SPEED =
Expand Down Expand Up @@ -74,10 +74,9 @@ public InteractionResult interact(Player player, InteractionHand hand) {
}

/**
* 操縦している乗客<br>
* 本来は常にnullなので乗客がいた時にそれを返却するように更新
* 操縦しているLivingEntity
*
* @return 乗客
* @return あればそのLivingEntity、なければnull
*/
@Override
public LivingEntity getControllingPassenger() {
Expand Down Expand Up @@ -118,7 +117,7 @@ public boolean isPushable() {
}

/**
* クリック判定を発生させるかどうかのようだ
* クリック判定を発生させるかどうかだと思われる
*
* @return もちろん発生させる じゃないと乗れない
*/
Expand Down Expand Up @@ -241,24 +240,25 @@ private void handlePlayerInput(Player player) {
// 前後進
float forward = 0.0f;
// 前進0.98, 後進-0.98
float W_S = player.zza;
float wS = player.zza;
// 左0.98, 右-0.98
float A_D = player.xxa;
float aD = player.xxa;

// PolygonTrainMod.LOGGER.info(String.valueOf(W_S) + ',' + A_D);
// 前進
if (W_S > 0) forward = 1.0f;
if (wS > 0) forward = 1.0f;
// 後進
if (W_S < 0) forward = -1.0f;
if (wS < 0) forward = -1.0f;

float turn = 0.0f;
// 左旋回
if (A_D > 0) turn = 1.0f;
if (aD > 0) turn = 1.0f;
// 右旋回
if (A_D < 0) turn = -1.0f;
if (aD < 0) turn = -1.0f;

// それはそうと適当に操作を反映
this.setYRot(this.getYRot() + turn);
this.setYRot(this.getYRot() - turn);
// TODO: 旋回に対応
this.setDeltaMovement(this.getDeltaMovement().x, this.getDeltaMovement().y, -forward);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

現在の実装では、setDeltaMovementのz成分に-forwardを直接設定しているため、自動車は向きに関わらず常にワールド座標のZ軸方向にしか移動しません。TODOコメントで旋回への対応が示されていますが、これは車両の挙動として重大なバグです。車両の向き(Y-Rot)を考慮して移動ベクトルを計算する必要があります。

Suggested change
this.setDeltaMovement(this.getDeltaMovement().x, this.getDeltaMovement().y, -forward);
float yawRad = this.getYRot() * ((float)Math.PI / 180F);
double dx = -Mth.sin(yawRad) * forward;
double dz = Mth.cos(yawRad) * forward;
this.setDeltaMovement(dx, this.getDeltaMovement().y, dz);

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

対応不要


//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class PolygonTrainModEntities {
public static final Supplier<EntityType<CarEntity>> CAR = ENTITY_TYPES.register(
"car",
() -> EntityType.Builder.<CarEntity>of(CarEntity::new, MobCategory.MISC)
.sized(3.0f, 2.0f)
.clientTrackingRange(10)
.updateInterval(1)
.build("car")
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading