Skip to content

Commit 31c75ac

Browse files
committed
Start improving VolumePositionTranslators
Signed-off-by: Gabriel Harris-Rouquette <[email protected]>
1 parent 123d644 commit 31c75ac

File tree

4 files changed

+51
-29
lines changed

4 files changed

+51
-29
lines changed

src/main/java/org/spongepowered/api/util/rotation/Rotation.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.spongepowered.api.registry.DefaultedRegistryValue;
2828
import org.spongepowered.api.util.Angle;
2929
import org.spongepowered.api.util.annotation.CatalogedBy;
30+
import org.spongepowered.math.matrix.Matrix4d;
3031

3132
@CatalogedBy(Rotations.class)
3233
public interface Rotation extends DefaultedRegistryValue {
@@ -40,4 +41,37 @@ public interface Rotation extends DefaultedRegistryValue {
4041
*/
4142
Angle angle();
4243

44+
/**
45+
* Gets the {@link Matrix4d 4D rotation matrix} of this rotation.
46+
*
47+
* <p>Minecraft's coordinate system is different than traditional systems
48+
* applying the semantic meaning behind the {@code x} and {@code z} axis.
49+
* These natures are described as below:
50+
* </p>
51+
* <ul>
52+
* <li>The x-axis indicates the <b>east</b> (when positive) or <b>west</b>
53+
* (when negative) of the origin point {@code (0, 0, 0)}</li>
54+
* <li>The z-axis indicates the <b>south</b> (when positive) or <b>north</b>
55+
* (when negative) of the origin point {@code (0, 0, 0)}</li>
56+
* </ul>
57+
* <p>
58+
* These rules differ from traditional coordinate interpretations and
59+
* therefore may be unintuitive when a rotation of {@code 90} degrees will
60+
* instead rotate the coordinates {@code (1, 1, 1)} across the pivot
61+
* {@code (0, 0, 0)}
62+
* </p>
63+
*
64+
* @return The euler matrix that represents this rotation in the X-Z plane.
65+
*/
66+
default Matrix4d toRotationMatrix() {
67+
final int cos = (int) Math.round(Math.cos(Math.toRadians(-this.angle().degrees())));
68+
final int sin = (int) Math.round(Math.sin(Math.toRadians(-this.angle().degrees())));
69+
return Matrix4d.from(
70+
cos, 0, sin, 0,
71+
0, 1, 0, 0,
72+
-sin, 0, cos, 0,
73+
0, 0, 0, 1
74+
);
75+
}
76+
4377
}

src/main/java/org/spongepowered/api/world/volume/archetype/ArchetypeVolume.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
import org.spongepowered.api.event.CauseStackManager;
2929
import org.spongepowered.api.event.EventContextKeys;
3030
import org.spongepowered.api.event.cause.entity.SpawnType;
31-
import org.spongepowered.api.util.mirror.Mirror;
32-
import org.spongepowered.api.util.rotation.Rotation;
31+
import org.spongepowered.api.util.transformation.Transformation;
3332
import org.spongepowered.api.world.BlockChangeFlags;
3433
import org.spongepowered.api.world.server.ServerWorld;
3534
import org.spongepowered.api.world.volume.archetype.block.entity.BlockEntityArchetypeVolume;
@@ -40,6 +39,7 @@
4039
import org.spongepowered.api.world.volume.stream.VolumeApplicators;
4140
import org.spongepowered.api.world.volume.stream.VolumeCollectors;
4241
import org.spongepowered.api.world.volume.stream.VolumePositionTranslators;
42+
import org.spongepowered.math.vector.Vector3d;
4343
import org.spongepowered.math.vector.Vector3i;
4444

4545
import java.util.Objects;
@@ -50,6 +50,17 @@ public interface ArchetypeVolume extends BlockVolume.Modifiable<ArchetypeVolume>
5050
EntityArchetypeVolume.Modifiable<ArchetypeVolume>,
5151
BiomeVolume.Modifiable<ArchetypeVolume> {
5252

53+
ArchetypeVolume transform(Transformation transformation);
54+
55+
/**
56+
* Gets the logical center of a volume, considering the decimal coordinates,
57+
* the block's center location would have an offset of {@code 0.5}
58+
* @return
59+
*/
60+
default Vector3d logicalCenter() {
61+
return this.blockMin().toDouble().add(this.blockSize().toDouble().div(2));
62+
}
63+
5364
/**
5465
* Attempts to apply all of the contents of this
5566
* {@link ArchetypeVolume volume} onto the target {@link ServerWorld world}

src/main/java/org/spongepowered/api/world/volume/stream/VolumePositionTranslators.java

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
package org.spongepowered.api.world.volume.stream;
2626

2727
import org.spongepowered.api.block.BlockState;
28-
import org.spongepowered.api.block.entity.BlockEntity;
29-
import org.spongepowered.api.entity.Entity;
3028
import org.spongepowered.api.util.rotation.Rotation;
3129
import org.spongepowered.api.world.volume.Volume;
3230
import org.spongepowered.math.imaginary.Quaterniond;
@@ -47,29 +45,13 @@ public static <W extends Volume> VolumePositionTranslator<W, BlockState> rotateB
4745
return VolumePositionTranslators.rotateOn(start, center, rotation, (position, state) -> state.rotate(rotation));
4846
}
4947

50-
public static <W extends Volume> VolumePositionTranslator<W, Entity> rotateEntitiesOn(final Vector3i start, final Vector3d center, final Rotation rotation) {
51-
return VolumePositionTranslators.rotateOn(start, center, rotation, (position, entity) -> {
52-
final Quaterniond q = Quaterniond.fromAngleDegAxis(rotation.angle().degrees(), 0, 1, 0);
53-
final Vector3d newPosition = q.rotate(entity.position().sub(center.toDouble())).add(center.toDouble());
54-
entity.setRotation(entity.rotation().add(0, (float) rotation.angle().degrees() / 360, 0));
55-
entity.setPosition(newPosition);
56-
return entity;
57-
});
58-
}
59-
60-
public static <W extends Volume> VolumePositionTranslator<W, BlockEntity> rotateBlockEntitiesOn(final Vector3i start, final Vector3i center,
61-
final Rotation rotation
62-
) {
63-
return VolumePositionTranslators.rotateOn(start, center.toDouble(), rotation, (position, blockEntity) -> blockEntity.rotate(rotation));
64-
}
65-
6648
public static <W extends Volume, E> VolumePositionTranslator<W, E> rotateOn(final Vector3i start, final Vector3d center, final Rotation rotation,
6749
final BiFunction<Vector3i, E, E> elementRotation
6850
) {
6951
return element -> {
7052
final Quaterniond q = Quaterniond.fromAngleDegAxis(rotation.angle().degrees(), 0, 1, 0);
71-
final Vector3i v = q.rotate(element.position().sub(center).toDouble()).toInt().add(center);
72-
return VolumeElement.of(element.volume(), elementRotation.apply(element.type()), v);
53+
final Vector3i v = q.rotate(center).add(element.position().toDouble().sub(start.toDouble())).round().toInt();
54+
return VolumeElement.of(element.volume(), elementRotation.apply(v, element.type()), v);
7355
};
7456
}
7557

@@ -86,12 +68,5 @@ public static <W extends Volume, E> VolumePositionTranslator<W, E> position(fina
8668
return element -> VolumeElement.of(element.volume(), element.type(), func.apply(element.position()));
8769
}
8870

89-
public static <W extends Volume, E> VolumePositionTranslator<W, E> offsetPosition(final Vector3i origin,
90-
Vector3i originalOrigin
91-
) {
92-
final Vector3i diff = origin.sub(originalOrigin);
93-
return element -> VolumeElement.of(element.volume(), element.type(), element.position().add(diff));
94-
}
95-
9671
private VolumePositionTranslators() {}
9772
}

src/main/java/org/spongepowered/api/world/volume/stream/VolumeStream.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ default VolumeStream<V, Optional<? extends T>> flatMap(final Function<VolumeElem
8282
return this.flatMap((volume, value, x, y, z) -> mapper.apply(VolumeElement.of(volume, value, new Vector3i(x, y, z))));
8383
}
8484

85+
VolumeStream<V, T> transform(VolumePositionTranslator<V, T> transformer);
86+
8587
long count();
8688

8789
boolean allMatch(VolumePredicate<V, ? super T> predicate);

0 commit comments

Comments
 (0)