Added rotating AABBs through lots of pain and suffering
- Collision models now rotate to match entity's general up direction - Extracted rotation logic from RelRelation into AxisRotations - Test:PlanetGravityModel is now properly centered - Fixed some small bugs
This commit is contained in:
parent
2d55d4db51
commit
bd5a1fa04e
@ -36,8 +36,8 @@ import ru.windcorp.progressia.client.world.tile.TileRender;
|
|||||||
import ru.windcorp.progressia.client.world.tile.TileRenderNone;
|
import ru.windcorp.progressia.client.world.tile.TileRenderNone;
|
||||||
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
|
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
|
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelRelation;
|
|
||||||
|
|
||||||
public class ChunkRenderModel implements Renderable {
|
public class ChunkRenderModel implements Renderable {
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public class ChunkRenderModel implements Renderable {
|
|||||||
chunk.getY() * ChunkData.BLOCKS_PER_CHUNK,
|
chunk.getY() * ChunkData.BLOCKS_PER_CHUNK,
|
||||||
chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK
|
chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK
|
||||||
).translate(offset, offset, offset)
|
).translate(offset, offset, offset)
|
||||||
.mul(RelRelation.getResolutionMatrix4(chunk.getUp()))
|
.mul(AxisRotations.getResolutionMatrix4(chunk.getUp()))
|
||||||
.translate(-offset, -offset, -offset);
|
.translate(-offset, -offset, -offset);
|
||||||
|
|
||||||
model.render(renderer);
|
model.render(renderer);
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package ru.windcorp.progressia.common.collision;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
|
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
||||||
|
|
||||||
|
public class AABBRotator implements AABBoid {
|
||||||
|
|
||||||
|
private class AABBRotatorWall implements Wall {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
public AABBRotatorWall(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOrigin(Vec3 output) {
|
||||||
|
parent.getWall(id).getOrigin(output);
|
||||||
|
AxisRotations.resolve(output, upSupplier.get(), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getWidth(Vec3 output) {
|
||||||
|
parent.getWall(id).getWidth(output);
|
||||||
|
AxisRotations.resolve(output, upSupplier.get(), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getHeight(Vec3 output) {
|
||||||
|
parent.getWall(id).getHeight(output);
|
||||||
|
AxisRotations.resolve(output, upSupplier.get(), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Supplier<AbsFace> upSupplier;
|
||||||
|
private final Supplier<Vec3> hingeSupplier;
|
||||||
|
private final AABBoid parent;
|
||||||
|
|
||||||
|
private final AABBRotatorWall[] walls = new AABBRotatorWall[AbsFace.BLOCK_FACE_COUNT];
|
||||||
|
|
||||||
|
{
|
||||||
|
for (int id = 0; id < walls.length; ++id) {
|
||||||
|
walls[id] = new AABBRotatorWall(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AABBRotator(Supplier<AbsFace> upSupplier, Supplier<Vec3> hingeSupplier, AABBoid parent) {
|
||||||
|
this.upSupplier = upSupplier;
|
||||||
|
this.hingeSupplier = hingeSupplier;
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOrigin(Vec3 origin) {
|
||||||
|
Vec3 relativeOrigin = Vectors.grab3();
|
||||||
|
Vec3 hinge = hingeSupplier.get();
|
||||||
|
|
||||||
|
origin.sub(hinge, relativeOrigin);
|
||||||
|
AxisRotations.relativize(relativeOrigin, upSupplier.get(), relativeOrigin);
|
||||||
|
relativeOrigin.add(hinge);
|
||||||
|
|
||||||
|
parent.setOrigin(relativeOrigin);
|
||||||
|
|
||||||
|
Vectors.release(relativeOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveOrigin(Vec3 displacement) {
|
||||||
|
parent.moveOrigin(displacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getOrigin(Vec3 output) {
|
||||||
|
parent.getOrigin(output);
|
||||||
|
Vec3 hinge = hingeSupplier.get();
|
||||||
|
|
||||||
|
output.sub(hinge);
|
||||||
|
AxisRotations.resolve(output, upSupplier.get(), output);
|
||||||
|
output.add(hinge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getSize(Vec3 output) {
|
||||||
|
parent.getSize(output);
|
||||||
|
AxisRotations.resolve(output, upSupplier.get(), output);
|
||||||
|
output.abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Wall getWall(int faceId) {
|
||||||
|
return walls[faceId];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CollisionModel rotate(Supplier<AbsFace> upSupplier, Supplier<Vec3> hingeSupplier, CollisionModel parent) {
|
||||||
|
if (parent instanceof AABBoid) {
|
||||||
|
return new AABBRotator(upSupplier, hingeSupplier, (AABBoid) parent);
|
||||||
|
} else if (parent instanceof CompoundCollisionModel) {
|
||||||
|
ImmutableList.Builder<CollisionModel> models = ImmutableList.builder();
|
||||||
|
|
||||||
|
for (CollisionModel original : ((CompoundCollisionModel) parent).getModels()) {
|
||||||
|
models.add(rotate(upSupplier, hingeSupplier, original));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CompoundCollisionModel(models.build());
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,12 +26,14 @@ import java.util.Objects;
|
|||||||
import glm.mat._3.Mat3;
|
import glm.mat._3.Mat3;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import ru.windcorp.jputil.chars.StringUtil;
|
import ru.windcorp.jputil.chars.StringUtil;
|
||||||
|
import ru.windcorp.progressia.common.collision.AABBRotator;
|
||||||
import ru.windcorp.progressia.common.collision.Collideable;
|
import ru.windcorp.progressia.common.collision.Collideable;
|
||||||
import ru.windcorp.progressia.common.collision.CollisionModel;
|
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||||
import ru.windcorp.progressia.common.state.IOContext;
|
import ru.windcorp.progressia.common.state.IOContext;
|
||||||
import ru.windcorp.progressia.common.state.StatefulObject;
|
import ru.windcorp.progressia.common.state.StatefulObject;
|
||||||
import ru.windcorp.progressia.common.util.Matrices;
|
import ru.windcorp.progressia.common.util.Matrices;
|
||||||
import ru.windcorp.progressia.common.world.generic.GenericEntity;
|
import ru.windcorp.progressia.common.world.generic.GenericEntity;
|
||||||
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
|
|
||||||
public class EntityData extends StatefulObject implements Collideable, GenericEntity {
|
public class EntityData extends StatefulObject implements Collideable, GenericEntity {
|
||||||
|
|
||||||
@ -51,6 +53,7 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn
|
|||||||
private long entityId;
|
private long entityId;
|
||||||
|
|
||||||
private CollisionModel collisionModel = null;
|
private CollisionModel collisionModel = null;
|
||||||
|
private CollisionModel rotatedCollisionModel = null;
|
||||||
|
|
||||||
private double age = 0;
|
private double age = 0;
|
||||||
|
|
||||||
@ -107,11 +110,16 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CollisionModel getCollisionModel() {
|
public CollisionModel getCollisionModel() {
|
||||||
|
return rotatedCollisionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CollisionModel getOriginalCollisionModel() {
|
||||||
return collisionModel;
|
return collisionModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCollisionModel(CollisionModel collisionModel) {
|
public void setCollisionModel(CollisionModel collisionModel) {
|
||||||
this.collisionModel = collisionModel;
|
this.collisionModel = collisionModel;
|
||||||
|
this.rotatedCollisionModel = AABBRotator.rotate(this::getUpFace, this::getPosition, collisionModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -164,6 +172,10 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn
|
|||||||
public Vec3 getUpVector() {
|
public Vec3 getUpVector() {
|
||||||
return upVector;
|
return upVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AbsFace getUpFace() {
|
||||||
|
return AbsFace.roundToFace(getUpVector());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets this entity's up vector without updating looking at-vector.
|
* Sets this entity's up vector without updating looking at-vector.
|
||||||
|
@ -25,8 +25,8 @@ import ru.windcorp.progressia.common.util.VectorUtil;
|
|||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
import ru.windcorp.progressia.common.world.Coordinates;
|
import ru.windcorp.progressia.common.world.Coordinates;
|
||||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
|
import ru.windcorp.progressia.common.world.rels.AxisRotations;
|
||||||
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
||||||
import ru.windcorp.progressia.common.world.rels.RelRelation;
|
|
||||||
|
|
||||||
public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack<TS, T, Self>> {
|
public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack<TS, T, Self>> {
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ public interface GenericChunk<Self extends GenericChunk<Self, B, T, TS>, B exten
|
|||||||
output.set(relativeBlockInChunk.x, relativeBlockInChunk.y, relativeBlockInChunk.z);
|
output.set(relativeBlockInChunk.x, relativeBlockInChunk.y, relativeBlockInChunk.z);
|
||||||
output.mul(2).sub(offset);
|
output.mul(2).sub(offset);
|
||||||
|
|
||||||
RelRelation.resolve(output, getUp(), output);
|
AxisRotations.resolve(output, getUp(), output);
|
||||||
|
|
||||||
output.add(offset).div(2);
|
output.add(offset).div(2);
|
||||||
|
|
||||||
|
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package ru.windcorp.progressia.common.world.rels;
|
||||||
|
|
||||||
|
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.NEG_X;
|
||||||
|
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.NEG_Y;
|
||||||
|
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.NEG_Z;
|
||||||
|
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.POS_X;
|
||||||
|
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.POS_Y;
|
||||||
|
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.POS_Z;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import glm.mat._3.Mat3;
|
||||||
|
import glm.mat._4.Mat4;
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import glm.vec._3.i.Vec3i;
|
||||||
|
import ru.windcorp.progressia.common.util.VectorUtil;
|
||||||
|
import ru.windcorp.progressia.common.util.VectorUtil.SignedAxis;
|
||||||
|
|
||||||
|
public class AxisRotations {
|
||||||
|
|
||||||
|
private static class Rotation {
|
||||||
|
private static class MyMat3i {
|
||||||
|
private final int m00, m01, m02, m10, m11, m12, m20, m21, m22;
|
||||||
|
|
||||||
|
public MyMat3i(Mat3 integerMatrix) {
|
||||||
|
this.m00 = (int) integerMatrix.m00;
|
||||||
|
this.m01 = (int) integerMatrix.m01;
|
||||||
|
this.m02 = (int) integerMatrix.m02;
|
||||||
|
this.m10 = (int) integerMatrix.m10;
|
||||||
|
this.m11 = (int) integerMatrix.m11;
|
||||||
|
this.m12 = (int) integerMatrix.m12;
|
||||||
|
this.m20 = (int) integerMatrix.m20;
|
||||||
|
this.m21 = (int) integerMatrix.m21;
|
||||||
|
this.m22 = (int) integerMatrix.m22;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3i mul(Vec3i right, Vec3i res) {
|
||||||
|
res.set(
|
||||||
|
m00 * right.x + m10 * right.y + m20 * right.z,
|
||||||
|
m01 * right.x + m11 * right.y + m21 * right.z,
|
||||||
|
m02 * right.x + m12 * right.y + m22 * right.z
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Mat3 resolutionMatrix3 = new Mat3();
|
||||||
|
private final Mat4 resolutionMatrix4 = new Mat4();
|
||||||
|
private final MyMat3i resolutionMatrix3i;
|
||||||
|
|
||||||
|
private final Mat3 relativizationMatrix3 = new Mat3();
|
||||||
|
private final Mat4 relativizationMatrix4 = new Mat4();
|
||||||
|
private final MyMat3i relativizationMatrix3i;
|
||||||
|
|
||||||
|
private Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) {
|
||||||
|
resolutionMatrix3.c0(computeUnitVectorAlong(northDestination));
|
||||||
|
resolutionMatrix3.c1(computeUnitVectorAlong(westDestination));
|
||||||
|
resolutionMatrix3.c2(computeUnitVectorAlong(upDestination));
|
||||||
|
|
||||||
|
resolutionMatrix3.toMat4(resolutionMatrix4);
|
||||||
|
resolutionMatrix3i = new MyMat3i(resolutionMatrix3);
|
||||||
|
|
||||||
|
relativizationMatrix3.set(resolutionMatrix3).transpose();
|
||||||
|
relativizationMatrix4.set(resolutionMatrix4).transpose();
|
||||||
|
relativizationMatrix3i = new MyMat3i(relativizationMatrix3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vec3 computeUnitVectorAlong(SignedAxis signedAxis) {
|
||||||
|
Vec3 result = new Vec3(0, 0, 0);
|
||||||
|
VectorUtil.set(result, signedAxis.getAxis(), signedAxis.getSign());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the resolutionMatrix3
|
||||||
|
*/
|
||||||
|
public Mat3 getResolutionMatrix3() {
|
||||||
|
return resolutionMatrix3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the resolutionMatrix4
|
||||||
|
*/
|
||||||
|
public Mat4 getResolutionMatrix4() {
|
||||||
|
return resolutionMatrix4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the relativizationMatrix3
|
||||||
|
*/
|
||||||
|
public Mat3 getRelativizationMatrix3() {
|
||||||
|
return relativizationMatrix3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the relativizationMatrix4
|
||||||
|
*/
|
||||||
|
public Mat4 getRelativizationMatrix4() {
|
||||||
|
return relativizationMatrix4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3i resolve(Vec3i output, Vec3i input) {
|
||||||
|
if (output == null) {
|
||||||
|
output = new Vec3i();
|
||||||
|
}
|
||||||
|
resolutionMatrix3i.mul(input, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3i relativize(Vec3i output, Vec3i input) {
|
||||||
|
if (output == null) {
|
||||||
|
output = new Vec3i();
|
||||||
|
}
|
||||||
|
relativizationMatrix3i.mul(input, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 resolve(Vec3 output, Vec3 input) {
|
||||||
|
if (output == null) {
|
||||||
|
output = new Vec3();
|
||||||
|
}
|
||||||
|
resolutionMatrix3.mul(input, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 relativize(Vec3 output, Vec3 input) {
|
||||||
|
if (output == null) {
|
||||||
|
output = new Vec3();
|
||||||
|
}
|
||||||
|
relativizationMatrix3.mul(input, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Map<AbsFace, Rotation> TRANSFORMATIONS = AbsFace.mapToFaces(
|
||||||
|
new Rotation(POS_X, POS_Y, POS_Z),
|
||||||
|
new Rotation(POS_X, NEG_Y, NEG_Z),
|
||||||
|
new Rotation(POS_Z, NEG_Y, POS_X),
|
||||||
|
new Rotation(POS_Z, POS_Y, NEG_X),
|
||||||
|
new Rotation(POS_Z, NEG_X, NEG_Y),
|
||||||
|
new Rotation(POS_Z, POS_X, POS_Y)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Vec3i resolve(Vec3i relative, AbsFace up, Vec3i output) {
|
||||||
|
return TRANSFORMATIONS.get(up).resolve(output, relative);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 resolve(Vec3 relative, AbsFace up, Vec3 output) {
|
||||||
|
return TRANSFORMATIONS.get(up).resolve(output, relative);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3i relativize(Vec3i absolute, AbsFace up, Vec3i output) {
|
||||||
|
return TRANSFORMATIONS.get(up).relativize(output, absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 relativize(Vec3 absolute, AbsFace up, Vec3 output) {
|
||||||
|
return TRANSFORMATIONS.get(up).relativize(output, absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat3 getResolutionMatrix3(AbsFace up) {
|
||||||
|
return TRANSFORMATIONS.get(up).getResolutionMatrix3();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat4 getResolutionMatrix4(AbsFace up) {
|
||||||
|
return TRANSFORMATIONS.get(up).getResolutionMatrix4();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat3 getRelativizationMatrix3(AbsFace up) {
|
||||||
|
return TRANSFORMATIONS.get(up).getRelativizationMatrix3();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat4 getRelativizationMatrix4(AbsFace up) {
|
||||||
|
return TRANSFORMATIONS.get(up).getRelativizationMatrix4();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -37,7 +37,7 @@ public class BlockFaceResolver {
|
|||||||
for (AbsFace up : AbsFace.getFaces()) {
|
for (AbsFace up : AbsFace.getFaces()) {
|
||||||
for (RelFace relative : RelFace.getFaces()) {
|
for (RelFace relative : RelFace.getFaces()) {
|
||||||
|
|
||||||
AbsFace absolute = (AbsFace) AbsRelation.of(RelRelation.resolve(relative.getRelVector(), up, null));
|
AbsFace absolute = (AbsFace) AbsRelation.of(AxisRotations.resolve(relative.getRelVector(), up, null));
|
||||||
|
|
||||||
RESOLUTION_TABLE[up.getId()][relative.getId()] = absolute;
|
RESOLUTION_TABLE[up.getId()][relative.getId()] = absolute;
|
||||||
RELATIVIZATION_TABLE[up.getId()][absolute.getId()] = relative;
|
RELATIVIZATION_TABLE[up.getId()][absolute.getId()] = relative;
|
||||||
|
@ -17,122 +17,15 @@
|
|||||||
*/
|
*/
|
||||||
package ru.windcorp.progressia.common.world.rels;
|
package ru.windcorp.progressia.common.world.rels;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import glm.mat._3.Mat3;
|
|
||||||
import glm.mat._4.Mat4;
|
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.common.util.VectorUtil;
|
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
import ru.windcorp.progressia.common.util.VectorUtil.SignedAxis;
|
|
||||||
|
|
||||||
import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name stands for Relative Relation
|
* Name stands for Relative Relation
|
||||||
*/
|
*/
|
||||||
public class RelRelation extends BlockRelation {
|
public class RelRelation extends BlockRelation {
|
||||||
|
|
||||||
private static class Rotation {
|
|
||||||
private final SignedAxis northDestination;
|
|
||||||
private final SignedAxis westDestination;
|
|
||||||
private final SignedAxis upDestination;
|
|
||||||
|
|
||||||
private final Mat3 resolutionMatrix3 = new Mat3();
|
|
||||||
private final Mat4 resolutionMatrix4 = new Mat4();
|
|
||||||
|
|
||||||
private final Mat3 relativizationMatrix3 = new Mat3();
|
|
||||||
private final Mat4 relativizationMatrix4 = new Mat4();
|
|
||||||
|
|
||||||
private Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) {
|
|
||||||
this.northDestination = northDestination;
|
|
||||||
this.westDestination = westDestination;
|
|
||||||
this.upDestination = upDestination;
|
|
||||||
|
|
||||||
resolutionMatrix3.c0(apply(null, new Vec3(1, 0, 0)));
|
|
||||||
resolutionMatrix3.c1(apply(null, new Vec3(0, 1, 0)));
|
|
||||||
resolutionMatrix3.c2(apply(null, new Vec3(0, 0, 1)));
|
|
||||||
resolutionMatrix3.toMat4(resolutionMatrix4);
|
|
||||||
|
|
||||||
relativizationMatrix3.set(resolutionMatrix3).transpose();
|
|
||||||
relativizationMatrix4.set(resolutionMatrix4).transpose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the resolutionMatrix3
|
|
||||||
*/
|
|
||||||
public Mat3 getResolutionMatrix3() {
|
|
||||||
return resolutionMatrix3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the resolutionMatrix4
|
|
||||||
*/
|
|
||||||
public Mat4 getResolutionMatrix4() {
|
|
||||||
return resolutionMatrix4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the relativizationMatrix3
|
|
||||||
*/
|
|
||||||
public Mat3 getRelativizationMatrix3() {
|
|
||||||
return relativizationMatrix3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the relativizationMatrix4
|
|
||||||
*/
|
|
||||||
public Mat4 getRelativizationMatrix4() {
|
|
||||||
return relativizationMatrix4;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3i apply(Vec3i output, Vec3i input) {
|
|
||||||
if (output == null) {
|
|
||||||
output = new Vec3i();
|
|
||||||
}
|
|
||||||
|
|
||||||
int inX = input.x, inY = input.y, inZ = input.z;
|
|
||||||
|
|
||||||
set(output, inX, northDestination);
|
|
||||||
set(output, inY, westDestination);
|
|
||||||
set(output, inZ, upDestination);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void set(Vec3i output, int value, SignedAxis axis) {
|
|
||||||
VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3 apply(Vec3 output, Vec3 input) {
|
|
||||||
if (output == null) {
|
|
||||||
output = new Vec3();
|
|
||||||
}
|
|
||||||
|
|
||||||
float inX = input.x, inY = input.y, inZ = input.z;
|
|
||||||
|
|
||||||
set(output, inX, northDestination);
|
|
||||||
set(output, inY, westDestination);
|
|
||||||
set(output, inZ, upDestination);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void set(Vec3 output, float value, SignedAxis axis) {
|
|
||||||
VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static Map<AbsFace, Rotation> TRANSFORMATIONS = AbsFace.mapToFaces(
|
|
||||||
new Rotation(POS_X, POS_Y, POS_Z),
|
|
||||||
new Rotation(POS_X, NEG_Y, NEG_Z),
|
|
||||||
new Rotation(POS_Z, NEG_Y, POS_X),
|
|
||||||
new Rotation(POS_Z, POS_Y, NEG_X),
|
|
||||||
new Rotation(POS_Z, NEG_X, NEG_Y),
|
|
||||||
new Rotation(POS_Z, POS_X, POS_Y)
|
|
||||||
);
|
|
||||||
|
|
||||||
private final Vec3i vector = new Vec3i();
|
private final Vec3i vector = new Vec3i();
|
||||||
private final Vec3 floatVector = new Vec3();
|
private final Vec3 floatVector = new Vec3();
|
||||||
private final Vec3 normalized = new Vec3();
|
private final Vec3 normalized = new Vec3();
|
||||||
@ -242,38 +135,11 @@ public class RelRelation extends BlockRelation {
|
|||||||
|
|
||||||
private AbsRelation computeResolution(AbsFace up) {
|
private AbsRelation computeResolution(AbsFace up) {
|
||||||
Vec3i resolution = Vectors.grab3i();
|
Vec3i resolution = Vectors.grab3i();
|
||||||
resolve(vector, up, resolution);
|
AxisRotations.resolve(vector, up, resolution);
|
||||||
AbsRelation result = AbsRelation.of(resolution);
|
AbsRelation result = AbsRelation.of(resolution);
|
||||||
Vectors.release(resolution);
|
Vectors.release(resolution);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3i resolve(Vec3i relative, AbsFace up, Vec3i output) {
|
|
||||||
if (output == null) {
|
|
||||||
output = new Vec3i();
|
|
||||||
}
|
|
||||||
|
|
||||||
TRANSFORMATIONS.get(up).apply(output, relative);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Mat3 getResolutionMatrix3(AbsFace up) {
|
|
||||||
return TRANSFORMATIONS.get(up).getResolutionMatrix3();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Mat4 getResolutionMatrix4(AbsFace up) {
|
|
||||||
return TRANSFORMATIONS.get(up).getResolutionMatrix4();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Mat3 getRelativizationMatrix3(AbsFace up) {
|
|
||||||
return TRANSFORMATIONS.get(up).getRelativizationMatrix3();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Mat4 getRelativizationMatrix4(AbsFace up) {
|
|
||||||
return TRANSFORMATIONS.get(up).getRelativizationMatrix4();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vec3i getSample() {
|
protected Vec3i getSample() {
|
||||||
|
@ -43,9 +43,9 @@ public class TestPlanetGravityModel extends GravityModel {
|
|||||||
@Override
|
@Override
|
||||||
protected void doGetGravity(Vec3 pos, Vec3 output) {
|
protected void doGetGravity(Vec3 pos, Vec3 output) {
|
||||||
// Change to a CS where (0;0;0) is the center of the center chunk
|
// Change to a CS where (0;0;0) is the center of the center chunk
|
||||||
float px = pos.x - ChunkData.CHUNK_RADIUS;
|
float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f;
|
||||||
float py = pos.y - ChunkData.CHUNK_RADIUS;
|
float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f;
|
||||||
float pz = pos.z - ChunkData.CHUNK_RADIUS;
|
float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f;
|
||||||
|
|
||||||
// Assume weightlessness when too close to center
|
// Assume weightlessness when too close to center
|
||||||
if ((px*px + py*py + pz*pz) < INNER_RADIUS*INNER_RADIUS) {
|
if ((px*px + py*py + pz*pz) < INNER_RADIUS*INNER_RADIUS) {
|
||||||
|
Reference in New Issue
Block a user