EntityRenderer.java
net.minecraft.client.renderer.entity.EntityRenderer
信息
- 全限定名:net.minecraft.client.renderer.entity.EntityRenderer
- 类型:public abstract class
- 包:net.minecraft.client.renderer.entity
- 源码路径:src/main/java/net/minecraft/client/renderer/entity/EntityRenderer.java
- 起始行号:L37
- 职责:
TODO
字段/常量
-
SHADOW_POWER_FALLOFF_Y- 类型:
float - 修饰符:
private static final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
MAX_SHADOW_RADIUS- 类型:
float - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
NAMETAG_SCALE- 类型:
float - 修饰符:
public static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
entityRenderDispatcher- 类型:
EntityRenderDispatcher - 修饰符:
protected final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
font- 类型:
Font - 修饰符:
private final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
shadowRadius- 类型:
float - 修饰符:
protected - 源码定位:
L43 - 说明:
TODO
- 类型:
-
shadowStrength- 类型:
float - 修饰符:
protected - 源码定位:
L44 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
protected EntityRenderer(EntityRendererProvider.Context context) @ L46
- 构造器名:EntityRenderer
- 源码定位:L46
- 修饰符:protected
参数:
- context: EntityRendererProvider.Context
说明:
TODO
方法
下面的方法块按源码顺序生成。
public final int getPackedLightCoords(T entity, float partialTickTime) @ L51
- 方法名:getPackedLightCoords
- 源码定位:L51
- 返回类型:int
- 修饰符:public final
参数:
- entity: T
- partialTickTime: float
说明:
TODO
protected int getSkyLightLevel(T entity, BlockPos blockPos) @ L56
- 方法名:getSkyLightLevel
- 源码定位:L56
- 返回类型:int
- 修饰符:protected
参数:
- entity: T
- blockPos: BlockPos
说明:
TODO
protected int getBlockLightLevel(T entity, BlockPos blockPos) @ L60
- 方法名:getBlockLightLevel
- 源码定位:L60
- 返回类型:int
- 修饰符:protected
参数:
- entity: T
- blockPos: BlockPos
说明:
TODO
public boolean shouldRender(T entity, Frustum culler, double camX, double camY, double camZ) @ L64
- 方法名:shouldRender
- 源码定位:L64
- 返回类型:boolean
- 修饰符:public
参数:
- entity: T
- culler: Frustum
- camX: double
- camY: double
- camZ: double
说明:
TODO
protected AABB getBoundingBoxForCulling(T entity) @ L93
- 方法名:getBoundingBoxForCulling
- 源码定位:L93
- 返回类型:AABB
- 修饰符:protected
参数:
- entity: T
说明:
TODO
protected boolean affectedByCulling(T entity) @ L97
- 方法名:affectedByCulling
- 源码定位:L97
- 返回类型:boolean
- 修饰符:protected
参数:
- entity: T
说明:
TODO
public Vec3 getRenderOffset(S state) @ L101
- 方法名:getRenderOffset
- 源码定位:L101
- 返回类型:Vec3
- 修饰符:public
参数:
- state: S
说明:
TODO
public void submit(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) @ L105
- 方法名:submit
- 源码定位:L105
- 返回类型:void
- 修饰符:public
参数:
- state: S
- poseStack: PoseStack
- submitNodeCollector: SubmitNodeCollector
- camera: CameraRenderState
说明:
TODO
protected boolean shouldShowName(T entity, double distanceToCameraSq) @ L115
- 方法名:shouldShowName
- 源码定位:L115
- 返回类型:boolean
- 修饰符:protected
参数:
- entity: T
- distanceToCameraSq: double
说明:
TODO
public Font getFont() @ L119
- 方法名:getFont
- 源码定位:L119
- 返回类型:Font
- 修饰符:public
参数:
- 无
说明:
TODO
protected void submitNameDisplay(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) @ L123
- 方法名:submitNameDisplay
- 源码定位:L123
- 返回类型:void
- 修饰符:protected
参数:
- state: S
- poseStack: PoseStack
- submitNodeCollector: SubmitNodeCollector
- camera: CameraRenderState
说明:
TODO
protected final <S extends EntityRenderState> void submitNameDisplay(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera, int offset) @ L127
- 方法名:submitNameDisplay
- 源码定位:L127
- 返回类型:
void - 修饰符:protected final
参数:
- state: S
- poseStack: PoseStack
- submitNodeCollector: SubmitNodeCollector
- camera: CameraRenderState
- offset: int
说明:
TODO
protected Component getNameTag(T entity) @ L147
- 方法名:getNameTag
- 源码定位:L147
- 返回类型:Component
- 修饰符:protected
参数:
- entity: T
说明:
TODO
protected float getShadowRadius(S state) @ L151
- 方法名:getShadowRadius
- 源码定位:L151
- 返回类型:float
- 修饰符:protected
参数:
- state: S
说明:
TODO
protected float getShadowStrength(S state) @ L155
- 方法名:getShadowStrength
- 源码定位:L155
- 返回类型:float
- 修饰符:protected
参数:
- state: S
说明:
TODO
public abstract S createRenderState() @ L159
- 方法名:createRenderState
- 源码定位:L159
- 返回类型:S
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public final S createRenderState(T entity, float partialTicks) @ L161
- 方法名:createRenderState
- 源码定位:L161
- 返回类型:S
- 修饰符:public final
参数:
- entity: T
- partialTicks: float
说明:
TODO
public void extractRenderState(T entity, S state, float partialTicks) @ L168
- 方法名:extractRenderState
- 源码定位:L168
- 返回类型:void
- 修饰符:public
参数:
- entity: T
- state: S
- partialTicks: float
说明:
TODO
protected void finalizeRenderState(T entity, S state) @ L279
- 方法名:finalizeRenderState
- 源码定位:L279
- 返回类型:void
- 修饰符:protected
参数:
- entity: T
- state: S
说明:
TODO
private void extractShadow(S state, Minecraft minecraft, Level level) @ L285
- 方法名:extractShadow
- 源码定位:L285
- 返回类型:void
- 修饰符:private
参数:
- state: S
- minecraft: Minecraft
- level: Level
说明:
TODO
private void extractShadowPiece(S state, Level level, float pow, BlockPos.MutableBlockPos pos, ChunkAccess chunk) @ L321
- 方法名:extractShadowPiece
- 源码定位:L321
- 返回类型:void
- 修饰符:private
参数:
- state: S
- level: Level
- pow: float
- pos: BlockPos.MutableBlockPos
- chunk: ChunkAccess
说明:
TODO
private static Entity getServerSideEntity(Entity entity) @ L342
- 方法名:getServerSideEntity
- 源码定位:L342
- 返回类型:Entity
- 修饰符:private static
参数:
- entity: Entity
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public abstract class EntityRenderer<T extends Entity, S extends EntityRenderState> {
private static final float SHADOW_POWER_FALLOFF_Y = 0.5F;
private static final float MAX_SHADOW_RADIUS = 32.0F;
public static final float NAMETAG_SCALE = 0.025F;
protected final EntityRenderDispatcher entityRenderDispatcher;
private final Font font;
protected float shadowRadius;
protected float shadowStrength = 1.0F;
protected EntityRenderer(EntityRendererProvider.Context context) {
this.entityRenderDispatcher = context.getEntityRenderDispatcher();
this.font = context.getFont();
}
public final int getPackedLightCoords(T entity, float partialTickTime) {
BlockPos blockPos = BlockPos.containing(entity.getLightProbePosition(partialTickTime));
return LightCoordsUtil.pack(this.getBlockLightLevel(entity, blockPos), this.getSkyLightLevel(entity, blockPos));
}
protected int getSkyLightLevel(T entity, BlockPos blockPos) {
return entity.level().getBrightness(LightLayer.SKY, blockPos);
}
protected int getBlockLightLevel(T entity, BlockPos blockPos) {
return entity.isOnFire() ? 15 : entity.level().getBrightness(LightLayer.BLOCK, blockPos);
}
public boolean shouldRender(T entity, Frustum culler, double camX, double camY, double camZ) {
if (!entity.shouldRender(camX, camY, camZ)) {
return false;
} else if (!this.affectedByCulling(entity)) {
return true;
} else {
AABB boundingBox = this.getBoundingBoxForCulling(entity).inflate(0.5);
if (boundingBox.hasNaN() || boundingBox.getSize() == 0.0) {
boundingBox = new AABB(
entity.getX() - 2.0, entity.getY() - 2.0, entity.getZ() - 2.0, entity.getX() + 2.0, entity.getY() + 2.0, entity.getZ() + 2.0
);
}
if (culler.isVisible(boundingBox)) {
return true;
} else {
if (entity instanceof Leashable leashable) {
Entity leashHolder = leashable.getLeashHolder();
if (leashHolder != null) {
AABB leasherBox = this.entityRenderDispatcher.getRenderer(leashHolder).getBoundingBoxForCulling(leashHolder);
return culler.isVisible(leasherBox) || culler.isVisible(boundingBox.minmax(leasherBox));
}
}
return false;
}
}
}
protected AABB getBoundingBoxForCulling(T entity) {
return entity.getBoundingBox();
}
protected boolean affectedByCulling(T entity) {
return true;
}
public Vec3 getRenderOffset(S state) {
return state.passengerOffset != null ? state.passengerOffset : Vec3.ZERO;
}
public void submit(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) {
if (state.leashStates != null) {
for (EntityRenderState.LeashState leashState : state.leashStates) {
submitNodeCollector.submitLeash(poseStack, leashState);
}
}
this.submitNameDisplay(state, poseStack, submitNodeCollector, camera);
}
protected boolean shouldShowName(T entity, double distanceToCameraSq) {
return entity.shouldShowName() || entity.hasCustomName() && entity == this.entityRenderDispatcher.crosshairPickEntity;
}
public Font getFont() {
return this.font;
}
protected void submitNameDisplay(S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) {
this.submitNameDisplay(state, poseStack, submitNodeCollector, camera, 0);
}
protected final <S extends EntityRenderState> void submitNameDisplay(
S state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera, int offset
) {
poseStack.pushPose();
if (state.scoreText != null) {
submitNodeCollector.submitNameTag(
poseStack, state.nameTagAttachment, offset, state.scoreText, !state.isDiscrete, state.lightCoords, state.distanceToCameraSq, camera
);
poseStack.translate(0.0F, 9.0F * 1.15F * 0.025F, 0.0F);
}
if (state.nameTag != null) {
submitNodeCollector.submitNameTag(
poseStack, state.nameTagAttachment, offset, state.nameTag, !state.isDiscrete, state.lightCoords, state.distanceToCameraSq, camera
);
}
poseStack.popPose();
}
protected @Nullable Component getNameTag(T entity) {
return entity.getDisplayName();
}
protected float getShadowRadius(S state) {
return this.shadowRadius;
}
protected float getShadowStrength(S state) {
return this.shadowStrength;
}
public abstract S createRenderState();
public final S createRenderState(T entity, float partialTicks) {
S state = this.createRenderState();
this.extractRenderState(entity, state, partialTicks);
this.finalizeRenderState(entity, state);
return state;
}
public void extractRenderState(T entity, S state, float partialTicks) {
state.entityType = entity.getType();
state.x = Mth.lerp((double)partialTicks, entity.xOld, entity.getX());
state.y = Mth.lerp((double)partialTicks, entity.yOld, entity.getY());
state.z = Mth.lerp((double)partialTicks, entity.zOld, entity.getZ());
state.isInvisible = entity.isInvisible();
state.ageInTicks = entity.tickCount + partialTicks;
state.boundingBoxWidth = entity.getBbWidth();
state.boundingBoxHeight = entity.getBbHeight();
state.eyeHeight = entity.getEyeHeight();
if (entity.isPassenger()
&& entity.getVehicle() instanceof AbstractMinecart minecart
&& minecart.getBehavior() instanceof NewMinecartBehavior behavior
&& behavior.cartHasPosRotLerp()) {
double cartLerpX = Mth.lerp((double)partialTicks, minecart.xOld, minecart.getX());
double cartLerpY = Mth.lerp((double)partialTicks, minecart.yOld, minecart.getY());
double cartLerpZ = Mth.lerp((double)partialTicks, minecart.zOld, minecart.getZ());
state.passengerOffset = behavior.getCartLerpPosition(partialTicks).subtract(new Vec3(cartLerpX, cartLerpY, cartLerpZ));
} else {
state.passengerOffset = null;
}
if (this.entityRenderDispatcher.camera != null) {
state.distanceToCameraSq = this.entityRenderDispatcher.distanceToSqr(entity);
boolean shouldShowName = state.distanceToCameraSq < 4096.0 && this.shouldShowName(entity, state.distanceToCameraSq);
if (shouldShowName) {
state.nameTag = this.getNameTag(entity);
state.nameTagAttachment = entity.getAttachments().getNullable(EntityAttachment.NAME_TAG, 0, entity.getYRot(partialTicks));
} else {
state.nameTag = null;
}
if (state.distanceToCameraSq < 100.0) {
state.scoreText = entity.belowNameDisplay();
} else {
state.scoreText = null;
}
}
label77: {
state.isDiscrete = entity.isDiscrete();
Level level = entity.level();
if (entity instanceof Leashable leashable) {
Entity entityYRot = leashable.getLeashHolder();
if (entityYRot instanceof Entity) {
float entityYRotx = entity.getPreciseBodyRotation(partialTicks) * (float) (Math.PI / 180.0);
Vec3 attachOffset = leashable.getLeashOffset(partialTicks);
BlockPos entityEyePos = BlockPos.containing(entity.getEyePosition(partialTicks));
BlockPos roperEyePos = BlockPos.containing(entityYRot.getEyePosition(partialTicks));
int startBlockLight = this.getBlockLightLevel(entity, entityEyePos);
int endBlockLight = this.entityRenderDispatcher.getRenderer(entityYRot).getBlockLightLevel(entityYRot, roperEyePos);
int startSkyLight = level.getBrightness(LightLayer.SKY, entityEyePos);
int endSkyLight = level.getBrightness(LightLayer.SKY, roperEyePos);
boolean quadConnection = entityYRot.supportQuadLeashAsHolder() && leashable.supportQuadLeash();
int leashCount = quadConnection ? 4 : 1;
if (state.leashStates == null || state.leashStates.size() != leashCount) {
state.leashStates = new ArrayList<>(leashCount);
for (int i = 0; i < leashCount; i++) {
state.leashStates.add(new EntityRenderState.LeashState());
}
}
if (quadConnection) {
float roperYRot = entityYRot.getPreciseBodyRotation(partialTicks) * (float) (Math.PI / 180.0);
Vec3 holderPos = entityYRot.getPosition(partialTicks);
Vec3[] leashableAttachmentPoints = leashable.getQuadLeashOffsets();
Vec3[] roperAttachmentPoints = entityYRot.getQuadLeashHolderOffsets();
int i = 0;
while (true) {
if (i >= leashCount) {
break label77;
}
EntityRenderState.LeashState leashState = state.leashStates.get(i);
leashState.offset = leashableAttachmentPoints[i].yRot(-entityYRotx);
leashState.start = entity.getPosition(partialTicks).add(leashState.offset);
leashState.end = holderPos.add(roperAttachmentPoints[i].yRot(-roperYRot));
leashState.startBlockLight = startBlockLight;
leashState.endBlockLight = endBlockLight;
leashState.startSkyLight = startSkyLight;
leashState.endSkyLight = endSkyLight;
leashState.slack = false;
i++;
}
} else {
Vec3 rotatedAttachOffset = attachOffset.yRot(-entityYRotx);
EntityRenderState.LeashState leashState = state.leashStates.getFirst();
leashState.offset = rotatedAttachOffset;
leashState.start = entity.getPosition(partialTicks).add(rotatedAttachOffset);
leashState.end = entityYRot.getRopeHoldPosition(partialTicks);
leashState.startBlockLight = startBlockLight;
leashState.endBlockLight = endBlockLight;
leashState.startSkyLight = startSkyLight;
leashState.endSkyLight = endSkyLight;
break label77;
}
}
}
state.leashStates = null;
}
state.displayFireAnimation = entity.displayFireAnimation();
Minecraft minecraft = Minecraft.getInstance();
boolean appearsGlowing = minecraft.shouldEntityAppearGlowing(entity);
state.outlineColor = appearsGlowing ? ARGB.opaque(entity.getTeamColor()) : 0;
state.lightCoords = this.getPackedLightCoords(entity, partialTicks);
}
protected void finalizeRenderState(T entity, S state) {
Minecraft minecraft = Minecraft.getInstance();
Level level = entity.level();
this.extractShadow(state, minecraft, level);
}
private void extractShadow(S state, Minecraft minecraft, Level level) {
state.shadowPieces.clear();
if (minecraft.options.entityShadows().get() && !state.isInvisible) {
float shadowRadius = Math.min(this.getShadowRadius(state), 32.0F);
state.shadowRadius = shadowRadius;
if (shadowRadius > 0.0F) {
double distSq = state.distanceToCameraSq;
float pow = (float)((1.0 - distSq / 256.0) * this.getShadowStrength(state));
if (pow > 0.0F) {
int x0 = Mth.floor(state.x - shadowRadius);
int x1 = Mth.floor(state.x + shadowRadius);
int z0 = Mth.floor(state.z - shadowRadius);
int z1 = Mth.floor(state.z + shadowRadius);
float depth = Math.min(pow / 0.5F - 1.0F, shadowRadius);
int y0 = Mth.floor(state.y - depth);
int y1 = Mth.floor(state.y);
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
for (int z = z0; z <= z1; z++) {
for (int x = x0; x <= x1; x++) {
pos.set(x, 0, z);
ChunkAccess chunk = level.getChunk(pos);
for (int y = y0; y <= y1; y++) {
pos.setY(y);
this.extractShadowPiece(state, level, pow, pos, chunk);
}
}
}
}
}
} else {
state.shadowRadius = 0.0F;
}
}
private void extractShadowPiece(S state, Level level, float pow, BlockPos.MutableBlockPos pos, ChunkAccess chunk) {
float powerAtDepth = pow - (float)(state.y - pos.getY()) * 0.5F;
BlockPos belowPos = pos.below();
BlockState belowState = chunk.getBlockState(belowPos);
if (belowState.getRenderShape() != RenderShape.INVISIBLE) {
int brightness = level.getMaxLocalRawBrightness(pos);
if (brightness > 3) {
if (belowState.isCollisionShapeFullBlock(chunk, belowPos)) {
VoxelShape belowShape = belowState.getShape(chunk, belowPos);
if (!belowShape.isEmpty()) {
float alpha = Mth.clamp(powerAtDepth * 0.5F * Lightmap.getBrightness(level.dimensionType(), brightness), 0.0F, 1.0F);
float relativeX = (float)(pos.getX() - state.x);
float relativeY = (float)(pos.getY() - state.y);
float relativeZ = (float)(pos.getZ() - state.z);
state.shadowPieces.add(new EntityRenderState.ShadowPiece(relativeX, relativeY, relativeZ, belowShape, alpha));
}
}
}
}
}
private static @Nullable Entity getServerSideEntity(Entity entity) {
IntegratedServer server = Minecraft.getInstance().getSingleplayerServer();
if (server != null) {
ServerLevel level = server.getLevel(entity.level().dimension());
if (level != null) {
return level.getEntity(entity.getId());
}
}
return null;
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Lightmap.getBrightness()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用/构造调用/返回值 - 关联成员:
EntityRenderState.LeashState(), EntityRenderState.ShadowPiece(), LeashState(), ShadowPiece()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
BlockPos.MutableBlockPos(), BlockPos.containing(), MutableBlockPos()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ARGB.opaque()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
LightCoordsUtil.pack()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.clamp(), Mth.floor(), Mth.lerp()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
AABB()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
Vec3()
- 引用位置: