Camera.java
net.minecraft.client.Camera
信息
- 全限定名:net.minecraft.client.Camera
- 类型:public class
- 包:net.minecraft.client
- 源码路径:src/main/java/net/minecraft/client/Camera.java
- 起始行号:L42
- 实现:TrackedWaypoint.Camera
- 职责:
TODO
字段/常量
-
PROJECTION_Z_NEAR- 类型:
float - 修饰符:
public static final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
DEFAULT_CAMERA_DISTANCE- 类型:
float - 修饰符:
private static final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
FORWARDS- 类型:
Vector3f - 修饰符:
private static final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
UP- 类型:
Vector3f - 修饰符:
private static final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
LEFT- 类型:
Vector3f - 修饰符:
private static final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
BASE_HUD_FOV- 类型:
float - 修饰符:
public static final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
initialized- 类型:
boolean - 修饰符:
private - 源码定位:
L49 - 说明:
TODO
- 类型:
-
level- 类型:
Level - 修饰符:
private - 源码定位:
L50 - 说明:
TODO
- 类型:
-
entity- 类型:
Entity - 修饰符:
private - 源码定位:
L51 - 说明:
TODO
- 类型:
-
position- 类型:
Vec3 - 修饰符:
private - 源码定位:
L52 - 说明:
TODO
- 类型:
-
blockPosition- 类型:
BlockPos.MutableBlockPos - 修饰符:
private final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
forwards- 类型:
Vector3f - 修饰符:
private final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
panoramicForwards- 类型:
Vector3f - 修饰符:
private final - 源码定位:
L55 - 说明:
TODO
- 类型:
-
up- 类型:
Vector3f - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
left- 类型:
Vector3f - 修饰符:
private final - 源码定位:
L57 - 说明:
TODO
- 类型:
-
xRot- 类型:
float - 修饰符:
private - 源码定位:
L58 - 说明:
TODO
- 类型:
-
yRot- 类型:
float - 修饰符:
private - 源码定位:
L59 - 说明:
TODO
- 类型:
-
rotation- 类型:
Quaternionf - 修饰符:
private final - 源码定位:
L60 - 说明:
TODO
- 类型:
-
detached- 类型:
boolean - 修饰符:
private - 源码定位:
L61 - 说明:
TODO
- 类型:
-
eyeHeight- 类型:
float - 修饰符:
private - 源码定位:
L62 - 说明:
TODO
- 类型:
-
eyeHeightOld- 类型:
float - 修饰符:
private - 源码定位:
L63 - 说明:
TODO
- 类型:
-
projection- 类型:
Projection - 修饰符:
private final - 源码定位:
L64 - 说明:
TODO
- 类型:
-
cullFrustum- 类型:
Frustum - 修饰符:
private - 源码定位:
L65 - 说明:
TODO
- 类型:
-
capturedFrustum- 类型:
Frustum - 修饰符:
private - 源码定位:
L66 - 说明:
TODO
- 类型:
-
captureFrustum- 类型:
boolean - 修饰符:
package-private - 源码定位:
L67 - 说明:
TODO
- 类型:
-
cachedViewRotMatrix- 类型:
Matrix4f - 修饰符:
private final - 源码定位:
L68 - 说明:
TODO
- 类型:
-
cachedViewRotProjMatrix- 类型:
Matrix4f - 修饰符:
private final - 源码定位:
L69 - 说明:
TODO
- 类型:
-
lastProjectionVersion- 类型:
long - 修饰符:
private - 源码定位:
L70 - 说明:
TODO
- 类型:
-
matrixPropertiesDirty- 类型:
int - 修饰符:
private - 源码定位:
L71 - 说明:
TODO
- 类型:
-
DIRTY_VIEW_ROT- 类型:
int - 修饰符:
private static final - 源码定位:
L72 - 说明:
TODO
- 类型:
-
DIRTY_VIEW_ROT_PROJ- 类型:
int - 修饰符:
private static final - 源码定位:
L73 - 说明:
TODO
- 类型:
-
fovModifier- 类型:
float - 修饰符:
private - 源码定位:
L74 - 说明:
TODO
- 类型:
-
oldFovModifier- 类型:
float - 修饰符:
private - 源码定位:
L75 - 说明:
TODO
- 类型:
-
fov- 类型:
float - 修饰符:
private - 源码定位:
L76 - 说明:
TODO
- 类型:
-
hudFov- 类型:
float - 修饰符:
private - 源码定位:
L77 - 说明:
TODO
- 类型:
-
depthFar- 类型:
float - 修饰符:
private - 源码定位:
L78 - 说明:
TODO
- 类型:
-
isPanoramicMode- 类型:
boolean - 修饰符:
private - 源码定位:
L79 - 说明:
TODO
- 类型:
-
attributeProbe- 类型:
EnvironmentAttributeProbe - 修饰符:
private final - 源码定位:
L80 - 说明:
TODO
- 类型:
-
minecraft- 类型:
Minecraft - 修饰符:
private final - 源码定位:
L81 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.Camera.NearPlane- 类型:
class - 修饰符:
public static - 源码定位:
L499 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
public void tick() @ L83
- 方法名:tick
- 源码定位:L83
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void update(DeltaTracker deltaTracker) @ L93
- 方法名:update
- 源码定位:L93
- 返回类型:void
- 修饰符:public
参数:
- deltaTracker: DeltaTracker
说明:
TODO
public float getCameraEntityPartialTicks(DeltaTracker deltaTracker) @ L114
- 方法名:getCameraEntityPartialTicks
- 源码定位:L114
- 返回类型:float
- 修饰符:public
参数:
- deltaTracker: DeltaTracker
说明:
TODO
public void extractRenderState(CameraRenderState cameraState, float cameraEntityPartialTicks) @ L118
- 方法名:extractRenderState
- 源码定位:L118
- 返回类型:void
- 修饰符:public
参数:
- cameraState: CameraRenderState
- cameraEntityPartialTicks: float
说明:
TODO
private void tickFov() @ L157
- 方法名:tickFov
- 源码定位:L157
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private Matrix4f createProjectionMatrixForCulling() @ L173
- 方法名:createProjectionMatrixForCulling
- 源码定位:L173
- 返回类型:Matrix4f
- 修饰符:private
参数:
- 无
说明:
TODO
public Frustum getCullFrustum() @ L185
- 方法名:getCullFrustum
- 源码定位:L185
- 返回类型:Frustum
- 修饰符:public
参数:
- 无
说明:
TODO
private void prepareCullFrustum(Matrix4fc modelViewMatrix, Matrix4f projectionMatrixForCulling, Vec3 cameraPos) @ L189
- 方法名:prepareCullFrustum
- 源码定位:L189
- 返回类型:void
- 修饰符:private
参数:
- modelViewMatrix: Matrix4fc
- projectionMatrixForCulling: Matrix4f
- cameraPos: Vec3
说明:
TODO
public Frustum getCapturedFrustum() @ L203
- 方法名:getCapturedFrustum
- 源码定位:L203
- 返回类型:Frustum
- 修饰符:public
参数:
- 无
说明:
TODO
public void captureFrustum() @ L207
- 方法名:captureFrustum
- 源码定位:L207
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void killFrustum() @ L211
- 方法名:killFrustum
- 源码定位:L211
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private float calculateFov(float partialTicks) @ L215
- 方法名:calculateFov
- 源码定位:L215
- 返回类型:float
- 修饰符:private
参数:
- partialTicks: float
说明:
TODO
private float calculateHudFov(float partialTicks) @ L224
- 方法名:calculateHudFov
- 源码定位:L224
- 返回类型:float
- 修饰符:private
参数:
- partialTicks: float
说明:
TODO
private float modifyFovBasedOnDeathOrFluid(float partialTicks, float fov) @ L228
- 方法名:modifyFovBasedOnDeathOrFluid
- 源码定位:L228
- 返回类型:float
- 修饰符:private
参数:
- partialTicks: float
- fov: float
说明:
TODO
private void alignWithEntity(float partialTicks) @ L243
- 方法名:alignWithEntity
- 源码定位:L243
- 返回类型:void
- 修饰符:private
参数:
- partialTicks: float
说明:
TODO
private float getMaxZoom(float cameraDist) @ L291
- 方法名:getMaxZoom
- 源码定位:L291
- 返回类型:float
- 修饰符:private
参数:
- cameraDist: float
说明:
TODO
public boolean isPanoramicMode() @ L312
- 方法名:isPanoramicMode
- 源码定位:L312
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public float getFov() @ L316
- 方法名:getFov
- 源码定位:L316
- 返回类型:float
- 修饰符:public
参数:
- 无
说明:
TODO
private void setupPerspective(float zNear, float zFar, float fov, float width, float height) @ L320
- 方法名:setupPerspective
- 源码定位:L320
- 返回类型:void
- 修饰符:private
参数:
- zNear: float
- zFar: float
- fov: float
- width: float
- height: float
说明:
TODO
private void setupOrtho(float zNear, float zFar, float width, float height, boolean invertY) @ L324
- 方法名:setupOrtho
- 源码定位:L324
- 返回类型:void
- 修饰符:private
参数:
- zNear: float
- zFar: float
- width: float
- height: float
- invertY: boolean
说明:
TODO
protected void move(float forwards, float up, float right) @ L328
- 方法名:move
- 源码定位:L328
- 返回类型:void
- 修饰符:protected
参数:
- forwards: float
- up: float
- right: float
说明:
TODO
protected void setRotation(float yRot, float xRot) @ L333
- 方法名:setRotation
- 源码定位:L333
- 返回类型:void
- 修饰符:protected
参数:
- yRot: float
- xRot: float
说明:
TODO
protected void setPosition(double x, double y, double z) @ L343
- 方法名:setPosition
- 源码定位:L343
- 返回类型:void
- 修饰符:protected
参数:
- x: double
- y: double
- z: double
说明:
TODO
protected void setPosition(Vec3 position) @ L347
- 方法名:setPosition
- 源码定位:L347
- 返回类型:void
- 修饰符:protected
参数:
- position: Vec3
说明:
TODO
public Vec3 position() @ L352
- 方法名:position
- 源码定位:L352
- 返回类型:Vec3
- 修饰符:public
参数:
- 无
说明:
TODO
public BlockPos blockPosition() @ L357
- 方法名:blockPosition
- 源码定位:L357
- 返回类型:BlockPos
- 修饰符:public
参数:
- 无
说明:
TODO
public float xRot() @ L361
- 方法名:xRot
- 源码定位:L361
- 返回类型:float
- 修饰符:public
参数:
- 无
说明:
TODO
public float yRot() @ L365
- 方法名:yRot
- 源码定位:L365
- 返回类型:float
- 修饰符:public
参数:
- 无
说明:
TODO
public float yaw() @ L369
- 方法名:yaw
- 源码定位:L369
- 返回类型:float
- 修饰符:public
参数:
- 无
说明:
TODO
public Quaternionf rotation() @ L374
- 方法名:rotation
- 源码定位:L374
- 返回类型:Quaternionf
- 修饰符:public
参数:
- 无
说明:
TODO
public Matrix4f getViewRotationMatrix(Matrix4f dest) @ L378
- 方法名:getViewRotationMatrix
- 源码定位:L378
- 返回类型:Matrix4f
- 修饰符:public
参数:
- dest: Matrix4f
说明:
TODO
public Matrix4f getViewRotationProjectionMatrix(Matrix4f dest) @ L388
- 方法名:getViewRotationProjectionMatrix
- 源码定位:L388
- 返回类型:Matrix4f
- 修饰符:public
参数:
- dest: Matrix4f
说明:
TODO
public Entity entity() @ L401
- 方法名:entity
- 源码定位:L401
- 返回类型:Entity
- 修饰符:public
参数:
- 无
说明:
TODO
public void setEntity(Entity entity) @ L405
- 方法名:setEntity
- 源码定位:L405
- 返回类型:void
- 修饰符:public
参数:
- entity: Entity
说明:
TODO
public boolean isInitialized() @ L409
- 方法名:isInitialized
- 源码定位:L409
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isDetached() @ L413
- 方法名:isDetached
- 源码定位:L413
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public EnvironmentAttributeProbe attributeProbe() @ L417
- 方法名:attributeProbe
- 源码定位:L417
- 返回类型:EnvironmentAttributeProbe
- 修饰符:public
参数:
- 无
说明:
TODO
public Camera.NearPlane getNearPlane(float fov) @ L421
- 方法名:getNearPlane
- 源码定位:L421
- 返回类型:Camera.NearPlane
- 修饰符:public
参数:
- fov: float
说明:
TODO
public FogType getFluidInCamera() @ L431
- 方法名:getFluidInCamera
- 源码定位:L431
- 返回类型:FogType
- 修饰符:public
参数:
- 无
说明:
TODO
public Vector3fc forwardVector() @ L462
- 方法名:forwardVector
- 源码定位:L462
- 返回类型:Vector3fc
- 修饰符:public
参数:
- 无
说明:
TODO
public Vector3fc panoramicForwards() @ L466
- 方法名:panoramicForwards
- 源码定位:L466
- 返回类型:Vector3fc
- 修饰符:public
参数:
- 无
说明:
TODO
public Vector3fc upVector() @ L470
- 方法名:upVector
- 源码定位:L470
- 返回类型:Vector3fc
- 修饰符:public
参数:
- 无
说明:
TODO
public Vector3fc leftVector() @ L474
- 方法名:leftVector
- 源码定位:L474
- 返回类型:Vector3fc
- 修饰符:public
参数:
- 无
说明:
TODO
public void reset() @ L478
- 方法名:reset
- 源码定位:L478
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void setLevel(ClientLevel level) @ L485
- 方法名:setLevel
- 源码定位:L485
- 返回类型:void
- 修饰符:public
参数:
- level: ClientLevel
说明:
TODO
public void enablePanoramicMode() @ L489
- 方法名:enablePanoramicMode
- 源码定位:L489
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void disablePanoramicMode() @ L494
- 方法名:disablePanoramicMode
- 源码定位:L494
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class Camera implements TrackedWaypoint.Camera {
public static final float PROJECTION_Z_NEAR = 0.05F;
private static final float DEFAULT_CAMERA_DISTANCE = 4.0F;
private static final Vector3f FORWARDS = new Vector3f(0.0F, 0.0F, -1.0F);
private static final Vector3f UP = new Vector3f(0.0F, 1.0F, 0.0F);
private static final Vector3f LEFT = new Vector3f(-1.0F, 0.0F, 0.0F);
public static final float BASE_HUD_FOV = 70.0F;
private boolean initialized;
private @Nullable Level level;
private @Nullable Entity entity;
private Vec3 position = Vec3.ZERO;
private final BlockPos.MutableBlockPos blockPosition = new BlockPos.MutableBlockPos();
private final Vector3f forwards = new Vector3f(FORWARDS);
private final Vector3f panoramicForwards = new Vector3f(FORWARDS);
private final Vector3f up = new Vector3f(UP);
private final Vector3f left = new Vector3f(LEFT);
private float xRot;
private float yRot;
private final Quaternionf rotation = new Quaternionf();
private boolean detached;
private float eyeHeight;
private float eyeHeightOld;
private final Projection projection = new Projection();
private Frustum cullFrustum = new Frustum(new Matrix4f(), new Matrix4f());
private @Nullable Frustum capturedFrustum;
boolean captureFrustum;
private final Matrix4f cachedViewRotMatrix = new Matrix4f();
private final Matrix4f cachedViewRotProjMatrix = new Matrix4f();
private long lastProjectionVersion = -1L;
private int matrixPropertiesDirty = -1;
private static final int DIRTY_VIEW_ROT = 1;
private static final int DIRTY_VIEW_ROT_PROJ = 2;
private float fovModifier;
private float oldFovModifier;
private float fov;
private float hudFov;
private float depthFar;
private boolean isPanoramicMode;
private final EnvironmentAttributeProbe attributeProbe = new EnvironmentAttributeProbe();
private final Minecraft minecraft = Minecraft.getInstance();
public void tick() {
if (this.level != null && this.entity != null) {
this.eyeHeightOld = this.eyeHeight;
this.eyeHeight = this.eyeHeight + (this.entity.getEyeHeight() - this.eyeHeight) * 0.5F;
this.attributeProbe.tick(this.level, this.position);
}
this.tickFov();
}
public void update(DeltaTracker deltaTracker) {
float renderDistance = this.minecraft.options.getEffectiveRenderDistance() * 16;
this.depthFar = Math.max(renderDistance * 4.0F, (float)(this.minecraft.options.cloudRange().get() * 16));
LocalPlayer player = this.minecraft.player;
if (player != null && this.level != null) {
if (this.entity == null) {
this.setEntity(player);
}
float partialTicks = this.getCameraEntityPartialTicks(deltaTracker);
this.alignWithEntity(partialTicks);
this.fov = this.calculateFov(partialTicks);
this.hudFov = this.calculateHudFov(partialTicks);
this.prepareCullFrustum(this.getViewRotationMatrix(this.cachedViewRotMatrix), this.createProjectionMatrixForCulling(), this.position);
float windowWidth = this.minecraft.getWindow().getWidth();
float windowHeight = this.minecraft.getWindow().getHeight();
this.setupPerspective(0.05F, this.depthFar, this.fov, windowWidth, windowHeight);
this.initialized = true;
}
}
public float getCameraEntityPartialTicks(DeltaTracker deltaTracker) {
return this.level.tickRateManager().isEntityFrozen(this.entity) ? 1.0F : deltaTracker.getGameTimeDeltaPartialTick(true);
}
public void extractRenderState(CameraRenderState cameraState, float cameraEntityPartialTicks) {
cameraState.initialized = this.isInitialized();
cameraState.isPanoramicMode = this.isPanoramicMode;
cameraState.pos = this.position();
cameraState.xRot = this.xRot;
cameraState.yRot = this.yRot;
cameraState.blockPos = this.blockPosition();
cameraState.orientation.set(this.rotation());
cameraState.cullFrustum.set(this.cullFrustum);
cameraState.depthFar = this.depthFar;
this.projection.getMatrix(cameraState.projectionMatrix);
this.getViewRotationMatrix(cameraState.viewRotationMatrix);
if (this.entity instanceof LivingEntity livingEntity) {
cameraState.entityRenderState.isLiving = true;
cameraState.entityRenderState.isSleeping = livingEntity.isSleeping();
cameraState.entityRenderState.doesMobEffectBlockSky = livingEntity.hasEffect(MobEffects.BLINDNESS) || livingEntity.hasEffect(MobEffects.DARKNESS);
cameraState.entityRenderState.isDeadOrDying = livingEntity.isDeadOrDying();
cameraState.entityRenderState.hurtDir = livingEntity.getHurtDir();
cameraState.entityRenderState.hurtTime = livingEntity.hurtTime - cameraEntityPartialTicks;
cameraState.entityRenderState.deathTime = livingEntity.deathTime + cameraEntityPartialTicks;
cameraState.entityRenderState.hurtDuration = livingEntity.hurtDuration;
} else {
cameraState.entityRenderState.isLiving = false;
cameraState.entityRenderState.isSleeping = false;
cameraState.entityRenderState.doesMobEffectBlockSky = false;
}
if (this.entity instanceof AbstractClientPlayer player) {
cameraState.entityRenderState.isPlayer = true;
ClientAvatarState avatarState = player.avatarState();
cameraState.entityRenderState.backwardsInterpolatedWalkDistance = avatarState.getBackwardsInterpolatedWalkDistance(cameraEntityPartialTicks);
cameraState.entityRenderState.bob = avatarState.getInterpolatedBob(cameraEntityPartialTicks);
} else {
cameraState.entityRenderState.isPlayer = false;
}
cameraState.hudFov = this.hudFov;
}
private void tickFov() {
float targetFovModifier;
if (this.minecraft.getCameraEntity() instanceof AbstractClientPlayer player) {
Options options = this.minecraft.options;
boolean firstPerson = options.getCameraType().isFirstPerson();
float effectScale = options.fovEffectScale().get().floatValue();
targetFovModifier = player.getFieldOfViewModifier(firstPerson, effectScale);
} else {
targetFovModifier = 1.0F;
}
this.oldFovModifier = this.fovModifier;
this.fovModifier = this.fovModifier + (targetFovModifier - this.fovModifier) * 0.5F;
this.fovModifier = Mth.clamp(this.fovModifier, 0.1F, 1.5F);
}
private Matrix4f createProjectionMatrixForCulling() {
float fovForCulling = Math.max(this.fov, (float)this.minecraft.options.fov().get().intValue());
Matrix4f projection = new Matrix4f();
return projection.perspective(
fovForCulling * (float) (Math.PI / 180.0),
(float)this.minecraft.getWindow().getWidth() / this.minecraft.getWindow().getHeight(),
0.05F,
this.depthFar,
RenderSystem.getDevice().isZZeroToOne()
);
}
public Frustum getCullFrustum() {
return this.cullFrustum;
}
private void prepareCullFrustum(Matrix4fc modelViewMatrix, Matrix4f projectionMatrixForCulling, Vec3 cameraPos) {
if (this.capturedFrustum != null && !this.captureFrustum) {
this.cullFrustum = this.capturedFrustum;
} else {
this.cullFrustum = new Frustum(modelViewMatrix, projectionMatrixForCulling);
this.cullFrustum.prepare(cameraPos.x(), cameraPos.y(), cameraPos.z());
}
if (this.captureFrustum) {
this.capturedFrustum = this.cullFrustum;
this.captureFrustum = false;
}
}
public @Nullable Frustum getCapturedFrustum() {
return this.capturedFrustum;
}
public void captureFrustum() {
this.captureFrustum = true;
}
public void killFrustum() {
this.capturedFrustum = null;
}
private float calculateFov(float partialTicks) {
if (this.isPanoramicMode) {
return 90.0F;
} else {
float fov = this.minecraft.options.fov().get().intValue() * Mth.lerp(partialTicks, this.oldFovModifier, this.fovModifier);
return this.modifyFovBasedOnDeathOrFluid(partialTicks, fov);
}
}
private float calculateHudFov(float partialTicks) {
return this.modifyFovBasedOnDeathOrFluid(partialTicks, 70.0F);
}
private float modifyFovBasedOnDeathOrFluid(float partialTicks, float fov) {
if (this.entity instanceof LivingEntity cameraEntity && cameraEntity.isDeadOrDying()) {
float duration = Math.min(cameraEntity.deathTime + partialTicks, 20.0F);
fov /= (1.0F - 500.0F / (duration + 500.0F)) * 2.0F + 1.0F;
}
FogType state = this.getFluidInCamera();
if (state == FogType.LAVA || state == FogType.WATER) {
float effectScale = this.minecraft.options.fovEffectScale().get().floatValue();
fov *= Mth.lerp(effectScale, 1.0F, 0.85714287F);
}
return fov;
}
private void alignWithEntity(float partialTicks) {
if (this.entity.isPassenger()
&& this.entity.getVehicle() instanceof Minecart minecart
&& minecart.getBehavior() instanceof NewMinecartBehavior behavior
&& behavior.cartHasPosRotLerp()) {
Vec3 positionOffset = minecart.getPassengerRidingPosition(this.entity)
.subtract(minecart.position())
.subtract(this.entity.getVehicleAttachmentPoint(minecart))
.add(new Vec3(0.0, Mth.lerp(partialTicks, this.eyeHeightOld, this.eyeHeight), 0.0));
this.setRotation(this.entity.getViewYRot(partialTicks), this.entity.getViewXRot(partialTicks));
this.setPosition(behavior.getCartLerpPosition(partialTicks).add(positionOffset));
} else {
this.setRotation(this.entity.getViewYRot(partialTicks), this.entity.getViewXRot(partialTicks));
this.setPosition(
Mth.lerp((double)partialTicks, this.entity.xo, this.entity.getX()),
Mth.lerp((double)partialTicks, this.entity.yo, this.entity.getY()) + Mth.lerp(partialTicks, this.eyeHeightOld, this.eyeHeight),
Mth.lerp((double)partialTicks, this.entity.zo, this.entity.getZ())
);
}
this.detached = !this.minecraft.options.getCameraType().isFirstPerson();
if (this.detached) {
if (this.minecraft.options.getCameraType().isMirrored()) {
this.setRotation(this.yRot + 180.0F, -this.xRot);
}
float cameraDistance = 4.0F;
float cameraScale = 1.0F;
if (this.entity instanceof LivingEntity living) {
cameraScale = living.getScale();
cameraDistance = (float)living.getAttributeValue(Attributes.CAMERA_DISTANCE);
}
float mountScale = cameraScale;
float mountDistance = cameraDistance;
if (this.entity.isPassenger() && this.entity.getVehicle() instanceof LivingEntity mount) {
mountScale = mount.getScale();
mountDistance = (float)mount.getAttributeValue(Attributes.CAMERA_DISTANCE);
}
this.move(-this.getMaxZoom(Math.max(cameraScale * cameraDistance, mountScale * mountDistance)), 0.0F, 0.0F);
} else if (this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isSleeping()) {
Direction bedOrientation = ((LivingEntity)this.entity).getBedOrientation();
this.setRotation(bedOrientation != null ? bedOrientation.toYRot() - 180.0F : 0.0F, 0.0F);
this.move(0.0F, 0.3F, 0.0F);
}
}
private float getMaxZoom(float cameraDist) {
float jitterScale = 0.1F;
for (int i = 0; i < 8; i++) {
float offsetX = (i & 1) * 2 - 1;
float offsetY = (i >> 1 & 1) * 2 - 1;
float offsetZ = (i >> 2 & 1) * 2 - 1;
Vec3 from = this.position.add(offsetX * 0.1F, offsetY * 0.1F, offsetZ * 0.1F);
Vec3 to = from.add(new Vec3(this.forwards).scale(-cameraDist));
HitResult hitResult = this.level.clip(new ClipContext(from, to, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, this.entity));
if (hitResult.getType() != HitResult.Type.MISS) {
float distSq = (float)hitResult.getLocation().distanceToSqr(this.position);
if (distSq < Mth.square(cameraDist)) {
cameraDist = Mth.sqrt(distSq);
}
}
}
return cameraDist;
}
public boolean isPanoramicMode() {
return this.isPanoramicMode;
}
public float getFov() {
return this.fov;
}
private void setupPerspective(float zNear, float zFar, float fov, float width, float height) {
this.projection.setupPerspective(zNear, zFar, fov, width, height);
}
private void setupOrtho(float zNear, float zFar, float width, float height, boolean invertY) {
this.projection.setupOrtho(zNear, zFar, width, height, invertY);
}
protected void move(float forwards, float up, float right) {
Vector3f offset = new Vector3f(right, up, -forwards).rotate(this.rotation);
this.setPosition(new Vec3(this.position.x + offset.x, this.position.y + offset.y, this.position.z + offset.z));
}
protected void setRotation(float yRot, float xRot) {
this.xRot = xRot;
this.yRot = yRot;
this.rotation.rotationYXZ((float) Math.PI - yRot * (float) (Math.PI / 180.0), -xRot * (float) (Math.PI / 180.0), 0.0F);
FORWARDS.rotate(this.rotation, this.forwards);
UP.rotate(this.rotation, this.up);
LEFT.rotate(this.rotation, this.left);
this.matrixPropertiesDirty |= 3;
}
protected void setPosition(double x, double y, double z) {
this.setPosition(new Vec3(x, y, z));
}
protected void setPosition(Vec3 position) {
this.position = position;
this.blockPosition.set(position.x, position.y, position.z);
}
@Override
public Vec3 position() {
return this.position;
}
public BlockPos blockPosition() {
return this.blockPosition;
}
public float xRot() {
return this.xRot;
}
public float yRot() {
return this.yRot;
}
@Override
public float yaw() {
return Mth.wrapDegrees(this.yRot());
}
public Quaternionf rotation() {
return this.rotation;
}
public Matrix4f getViewRotationMatrix(Matrix4f dest) {
if ((this.matrixPropertiesDirty & 1) != 0) {
Quaternionf inverseRotation = this.rotation().conjugate(new Quaternionf());
this.cachedViewRotMatrix.rotation(inverseRotation);
this.matrixPropertiesDirty &= -2;
}
return dest.set(this.cachedViewRotMatrix);
}
public Matrix4f getViewRotationProjectionMatrix(Matrix4f dest) {
long projectionVersion = this.projection.getMatrixVersion();
if ((this.matrixPropertiesDirty & 2) != 0 || this.lastProjectionVersion != this.projection.getMatrixVersion()) {
this.getViewRotationMatrix(this.cachedViewRotMatrix);
this.projection.getMatrix(this.cachedViewRotProjMatrix);
this.cachedViewRotProjMatrix.mul(this.cachedViewRotMatrix);
this.matrixPropertiesDirty &= -3;
this.lastProjectionVersion = projectionVersion;
}
return dest.set(this.cachedViewRotProjMatrix);
}
public @Nullable Entity entity() {
return this.entity;
}
public void setEntity(Entity entity) {
this.entity = entity;
}
public boolean isInitialized() {
return this.initialized;
}
public boolean isDetached() {
return this.detached;
}
public EnvironmentAttributeProbe attributeProbe() {
return this.attributeProbe;
}
public Camera.NearPlane getNearPlane(float fov) {
double aspectRatio = (double)this.projection.width() / this.projection.height();
double planeHeight = Math.tan(fov * (float) (Math.PI / 180.0) / 2.0) * this.projection.zNear();
double planeWidth = planeHeight * aspectRatio;
Vec3 forwardsVec3 = new Vec3(this.forwards).scale(this.projection.zNear());
Vec3 leftVec3 = new Vec3(this.left).scale(planeWidth);
Vec3 upVec3 = new Vec3(this.up).scale(planeHeight);
return new Camera.NearPlane(forwardsVec3, leftVec3, upVec3);
}
public FogType getFluidInCamera() {
if (!this.initialized) {
return FogType.NONE;
} else {
FluidState fluidState1 = this.level.getFluidState(this.blockPosition);
if (fluidState1.is(FluidTags.WATER) && this.position.y < this.blockPosition.getY() + fluidState1.getHeight(this.level, this.blockPosition)) {
return FogType.WATER;
} else {
Camera.NearPlane plane = this.getNearPlane(this.minecraft.options.fov().get().intValue());
for (Vec3 point : Arrays.asList(plane.forward, plane.getTopLeft(), plane.getTopRight(), plane.getBottomLeft(), plane.getBottomRight())) {
Vec3 offsetPos = this.position.add(point);
BlockPos checkPos = BlockPos.containing(offsetPos);
FluidState fluidState = this.level.getFluidState(checkPos);
if (fluidState.is(FluidTags.LAVA)) {
if (offsetPos.y <= fluidState.getHeight(this.level, checkPos) + checkPos.getY()) {
return FogType.LAVA;
}
} else {
BlockState state = this.level.getBlockState(checkPos);
if (state.is(Blocks.POWDER_SNOW)) {
return FogType.POWDER_SNOW;
}
}
}
return FogType.NONE;
}
}
}
public Vector3fc forwardVector() {
return this.forwards;
}
public Vector3fc panoramicForwards() {
return this.panoramicForwards;
}
public Vector3fc upVector() {
return this.up;
}
public Vector3fc leftVector() {
return this.left;
}
public void reset() {
this.level = null;
this.entity = null;
this.attributeProbe.reset();
this.initialized = false;
}
public void setLevel(@Nullable ClientLevel level) {
this.level = level;
}
public void enablePanoramicMode() {
this.isPanoramicMode = true;
this.panoramicForwards.set(this.forwards);
}
public void disablePanoramicMode() {
this.isPanoramicMode = false;
}
@OnlyIn(Dist.CLIENT)
public static class NearPlane {
private final Vec3 forward;
private final Vec3 left;
private final Vec3 up;
private NearPlane(Vec3 forward, Vec3 left, Vec3 up) {
this.forward = forward;
this.left = left;
this.up = up;
}
public Vec3 getTopLeft() {
return this.forward.add(this.up).add(this.left);
}
public Vec3 getTopRight() {
return this.forward.add(this.up).subtract(this.left);
}
public Vec3 getBottomLeft() {
return this.forward.subtract(this.up).add(this.left);
}
public Vec3 getBottomRight() {
return this.forward.subtract(this.up).subtract(this.left);
}
public Vec3 getPointOnPlane(float x, float y) {
return this.forward.add(this.up.scale(y)).subtract(this.left.scale(x));
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
RenderSystem.getDevice()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
Projection()
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
Frustum()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用/构造调用/返回值 - 关联成员:
BlockPos.MutableBlockPos(), BlockPos.containing(), MutableBlockPos()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.clamp(), Mth.lerp(), Mth.sqrt(), Mth.square(), Mth.wrapDegrees()
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
EnvironmentAttributeProbe()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ClipContext()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
Vec3()
- 引用位置:
-
- 引用位置:
实现
- 引用位置: