Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Position based gravity among other things #648

Open
wants to merge 5 commits into
base: 1.18.x/main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -128,6 +128,19 @@ private void setRotationWithShipTransform(final float yaw, final float pitch, fi
this.left.transform(this.rotation);
}

@Unique
public void addRotation(final Quaterniondc quaterniondc) {
Copy link
Member

Choose a reason for hiding this comment

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

You should not add public functions to mixins, unless you are implementing an interface.

this.xRot += (float) quaterniondc.x();
this.yRot += (float) quaterniondc.y();
VectorConversionsMCKt.set(this.rotation, quaterniondc);
this.forwards.set(0.0F, 0.0F, 1.0F);
this.forwards.transform(this.rotation);
this.up.set(0.0F, 1.0F, 0.0F);
this.up.transform(this.rotation);
this.left.set(1.0F, 0.0F, 0.0F);
this.left.transform(this.rotation);
}

/**
* When in third person, do not block the camera on the ship the player is mounted to
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.valkyrienskies.mod.common.entity.ShipMountingEntity;

Expand Down Expand Up @@ -40,4 +41,18 @@ private List<Entity> redirectAiStep(final Level instance, final Entity entity, f

return getEntities.call(instance, entity, aabb);
}

@Unique
public void setPostion(float x, float y, float z) {
this.xo = x;
this.yo = y;
this.zo = z;
}

@Unique
public void offsetPostion(float x, float y, float z) {
this.xo += x;
this.yo += y;
this.zo += z;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.valkyrienskies.core.api.ships.ClientShip;
import org.valkyrienskies.core.apigame.world.ClientShipWorldCore;
import org.valkyrienskies.mod.api.PositionGravity;
import org.valkyrienskies.mod.client.IVSCamera;
import org.valkyrienskies.mod.common.IShipObjectWorldClientProvider;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
Expand Down Expand Up @@ -238,69 +239,95 @@ private void postRender(final float tickDelta, final long startTime, final boole
target = "Lnet/minecraft/client/renderer/LevelRenderer;prepareCullFrustum(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/world/phys/Vec3;Lcom/mojang/math/Matrix4f;)V"
)
)
private void setupCameraWithMountedShip(final LevelRenderer instance, final PoseStack ignore, final Vec3 vec3,
private void moveCamera( final LevelRenderer instance, final PoseStack ignore, final Vec3 vec3,
final Matrix4f matrix4f, final Operation<Void> prepareCullFrustum, final float partialTicks,
final long finishTimeNano, final PoseStack matrixStack) {
final long finishTimeNano, final PoseStack matrixStack){

final ClientLevel clientLevel = minecraft.level;
final Entity player = minecraft.player;
if (clientLevel == null || player == null) {
prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f);
return;
}
final Camera camera = this.mainCamera;
final ClientShip playerShipMountedTo =
VSGameUtilsKt.getShipObjectEntityMountedTo(clientLevel, player);
if (playerShipMountedTo == null) {
prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f);
return;
}
final Entity playerVehicle = player.getVehicle();
if (playerVehicle == null) {

if (clientLevel == null || player == null || camera == null) {
prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f);
return;
}

// Update [matrixStack] to mount the camera to the ship
final Vector3dc inShipPos =
VSGameUtilsKt.getPassengerPos(playerVehicle, player.getMyRidingOffset(), partialTicks);
if (playerShipMountedTo == null) {
// if you aren't mounted on a ship
final Vector3d force = new PositionGravity().playerEffect(minecraft.player);
if (force.length() >= 10){
final Quaternion forceDirection =
new Quaternion(0.0F, (float) force.x, (float) force.y, (float) force.z);

final Camera camera = this.mainCamera;
if (camera == null) {
prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f);
return;
}
((IVSCamera) camera).moveCamera(
this.minecraft.level,
this.minecraft.getCameraEntity() == null ? this.minecraft.player : this.minecraft.getCameraEntity(),
!this.minecraft.options.getCameraType().isFirstPerson(),
this.minecraft.options.getCameraType().isMirrored(),
partialTicks
);

matrixStack.mulPose(forceDirection);

((IVSCamera) camera).setupWithShipMounted(
this.minecraft.level,
this.minecraft.getCameraEntity() == null ? this.minecraft.player : this.minecraft.getCameraEntity(),
!this.minecraft.options.getCameraType().isFirstPerson(),
this.minecraft.options.getCameraType().isMirrored(),
partialTicks,
playerShipMountedTo,
inShipPos
);
// We also need to recompute [inverseViewRotationMatrix] after updating [matrixStack]
{
final Matrix3f matrix3f = matrixStack.last().normal().copy();
if (matrix3f.invert()) {
RenderSystem.setInverseViewRotationMatrix(matrix3f);
}
}

// Apply the ship render transform to [matrixStack]
final Quaternion invShipRenderRotation = VectorConversionsMCKt.toMinecraft(
playerShipMountedTo.getRenderTransform().getShipToWorldRotation().conjugate(new Quaterniond()));
matrixStack.mulPose(invShipRenderRotation);
final double fov = this.getFov(camera, partialTicks, true);

// We also need to recompute [inverseViewRotationMatrix] after updating [matrixStack]
{
final Matrix3f matrix3f = matrixStack.last().normal().copy();
if (matrix3f.invert()) {
RenderSystem.setInverseViewRotationMatrix(matrix3f);
prepareCullFrustum.call(instance, matrixStack, camera.getPosition(),
this.getProjectionMatrix(Math.max(fov, this.minecraft.options.fov)));
}
} else {
// if you're mounted on a ship
final Entity playerVehicle = player.getVehicle();
if (playerVehicle == null) {
prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f);
return;
}
}

// Camera FOV changes based on the position of the camera, so recompute FOV to account for the change of camera
// position.
final double fov = this.getFov(camera, partialTicks, true);
// Update [matrixStack] to mount the camera to the ship
final Vector3dc inShipPos =
VSGameUtilsKt.getPassengerPos(playerVehicle, player.getMyRidingOffset(), partialTicks);

// Use [camera.getPosition()] instead of [vec3] because mounting the player to the ship has changed the camera
// position.
prepareCullFrustum.call(instance, matrixStack, camera.getPosition(),
this.getProjectionMatrix(Math.max(fov, this.minecraft.options.fov)));
((IVSCamera) camera).setupWithShipMounted(
this.minecraft.level,
this.minecraft.getCameraEntity() == null ? this.minecraft.player : this.minecraft.getCameraEntity(),
!this.minecraft.options.getCameraType().isFirstPerson(),
this.minecraft.options.getCameraType().isMirrored(),
partialTicks,
playerShipMountedTo,
inShipPos
);

// Apply the ship render transform to [matrixStack]
final Quaternion invShipRenderRotation = VectorConversionsMCKt.toMinecraft(
playerShipMountedTo.getRenderTransform().getShipToWorldRotation().conjugate(new Quaterniond()));
matrixStack.mulPose(invShipRenderRotation);

// We also need to recompute [inverseViewRotationMatrix] after updating [matrixStack]
{
final Matrix3f matrix3f = matrixStack.last().normal().copy();
if (matrix3f.invert()) {
RenderSystem.setInverseViewRotationMatrix(matrix3f);
}
}

// Camera FOV changes based on the position of the camera, so recompute FOV to account for the change of camera
// position.
final double fov = this.getFov(camera, partialTicks, true);

// Use [camera.getPosition()] instead of [vec3] because mounting the player to the ship has changed the camera
// position.
prepareCullFrustum.call(instance, matrixStack, camera.getPosition(),
this.getProjectionMatrix(Math.max(fov, this.minecraft.options.fov)));
}
}
// endregion
}
123 changes: 123 additions & 0 deletions common/src/main/kotlin/org/valkyrienskies/mod/api/PositionGravity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package org.valkyrienskies.mod.api

import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
import org.joml.Vector3d
import org.joml.Vector3dc
import org.valkyrienskies.core.api.ships.ServerShip
import org.valkyrienskies.core.util.x
import org.valkyrienskies.core.util.y
import org.valkyrienskies.core.util.z
import org.valkyrienskies.mod.common.entity.MobWeights

class PositionGravity {
private lateinit var instances: Map<Vector3dc?, Double>
fun PositionGravity(
pos: Vector3dc,
mass: Double
) {
instances + Pair(pos, mass)
}

fun removePosition(
pos: Vector3dc
) {
instances - pos
}

fun entityEffect(
entity: LivingEntity
): Vector3d {
lateinit var forces: List<Vector3d>
instances.forEach{
val distance: Double =
entity.getPosition(0.0F).distanceTo(Vec3(it.key!!.x, it.key!!.x, it.key!!.x))
Vector3d(
force(
entity.deltaMovement.x, distance,
MobWeights.NORMAL_PLAYER.weight, it.value,
entity.position().x - it.key!!.x
),
force(
entity.deltaMovement.y, distance,
MobWeights.NORMAL_PLAYER.weight, it.value,
entity.position().y - it.key!!.y
),
force(
entity.deltaMovement.z, distance,
MobWeights.NORMAL_PLAYER.weight, it.value,
entity.position().z - it.key!!.z
)
)
}
lateinit var totalForce: Vector3d
forces.forEach {
totalForce.add(it.x, it.y, it.z)
}
return totalForce
}

fun playerEffect(
player: Player
): Vector3d {
lateinit var forces: List<Vector3d>
instances.forEach{
val distance: Double =
player.getPosition(0.0F).distanceTo(Vec3(it.key!!.x, it.key!!.x, it.key!!.x))
Vector3d(
force(
player.deltaMovement.x, distance,
MobWeights.NORMAL_PLAYER.weight, it.value,
player.position().x - it.key!!.x
),
force(
player.deltaMovement.y, distance,
MobWeights.NORMAL_PLAYER.weight, it.value,
player.position().y - it.key!!.y
),
force(
player.deltaMovement.z, distance,
MobWeights.NORMAL_PLAYER.weight, it.value,
player.position().z - it.key!!.z
)
)
}
lateinit var totalForce: Vector3d
forces.forEach {
totalForce.add(it.x, it.y, it.z)
}
return totalForce
}
fun shipEffect(
ship: ServerShip
): Vector3d {
lateinit var forces: List<Vector3d>
instances.forEach {
val distance: Double = ship.inertiaData.centerOfMassInShip.distance(it.key)
forces + Vector3d(
force(
ship.velocity.x, distance, ship.inertiaData.mass, it.value,
ship.inertiaData.centerOfMassInShip.x - it.key!!.x
),
force(
ship.velocity.y, distance, ship.inertiaData.mass, it.value,
ship.inertiaData.centerOfMassInShip.y - it.key!!.y
),
force(
ship.velocity.z, distance, ship.inertiaData.mass, it.value,
ship.inertiaData.centerOfMassInShip.z - it.key!!.z
)
)
}
lateinit var totalForce: Vector3d
forces.forEach {
totalForce.add(it.x, it.y, it.z)
}
return totalForce
}

private fun force(axis: Double, distance: Double, mass1: Double, mass2: Double, axisDistance: Double): Double {
return axis - ((mass1 * axisDistance) / distance)
}
}
Loading
Loading