diff --git a/api/src/main/java/ru/dragonestia/msb3/api/boot/DefaultBootstrap.java b/api/src/main/java/ru/dragonestia/msb3/api/boot/DefaultBootstrap.java index 97f4af5..4e0326d 100644 --- a/api/src/main/java/ru/dragonestia/msb3/api/boot/DefaultBootstrap.java +++ b/api/src/main/java/ru/dragonestia/msb3/api/boot/DefaultBootstrap.java @@ -3,14 +3,13 @@ package ru.dragonestia.msb3.api.boot; import lombok.extern.log4j.Log4j2; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.coordinate.Pos; +import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.GameMode; import net.minestom.server.entity.metadata.display.BlockDisplayMeta; import net.minestom.server.instance.Instance; import net.minestom.server.instance.block.Block; -import ru.dragonestia.msb3.api.entity.debug.DebugCollider; import ru.dragonestia.msb3.api.entity.debug.DebugLine; import ru.dragonestia.msb3.api.entity.debug.DebugMarker; import ru.dragonestia.msb3.api.entity.debug.DebugRendererEntity; @@ -53,18 +52,28 @@ public class DefaultBootstrap extends ServerInitializer { public void onServerStarted() { var instance = FlatWorldModule.getWorld().getInstance(); - drawLine(instance, new Pos(0, 12, 10), new Pos(5, 16, 20)); - drawLine(instance, new Pos(0, 12, -10), new Pos(5, 16, -20)); - drawLine(instance, new Pos(10, 16, 2), new Pos(5, 12, 3)); - drawLine(instance, new Pos(9, 20, 10), new Pos(-2, 18, 7)); + int radius = 20; + int length = 8; + var center = new Vec(0, 40, 0); + for (int i = -20; i < 40; i++) { + var rad = Math.toRadians(360.0 / 30 * i); + var normal = new Vec(Math.sin(rad), (i - 15.0) / 7, Math.cos(rad)).normalize(); + var startPos = center.add(normal.mul(radius, 1, radius)); + var endPos = startPos.add(normal.mul(length)); + drawLine(instance, startPos, endPos); + } - var collider = new DebugCollider("test", Block.ORANGE_STAINED_GLASS, new Vec(5, 5, 5), Component.text("Collider")); - collider.setInstance(instance, new Vec(30, 11, 10)); + drawLine(instance, new Vec(3, 20, 0), new Vec(3, 60, 0)); + drawLine(instance, new Vec(-3, 60, 0), new Vec(-3, 20, 0)); + drawLine(instance, new Vec(10, 60, 3), new Vec(-10, 60, 3)); + drawLine(instance, new Vec(-10, 60, -3), new Vec(10, 60, -3)); + drawLine(instance, new Vec(0, 57, 10), new Vec(0, 57, -10)); + drawLine(instance, new Vec(0, 53, -10), new Vec(0, 53, 10)); } private static final AtomicInteger I = new AtomicInteger(1); - private void drawLine(Instance instance, Pos startPos, Pos endPos) { + private void drawLine(Instance instance, Point startPos, Point endPos) { var id = I.getAndIncrement(); { var marker = new DebugMarker("test", Block.RED_CONCRETE, Component.text("[%s] START".formatted(id))); @@ -79,35 +88,21 @@ public class DefaultBootstrap extends ServerInitializer { var dist = startPos.distance(endPos); record LineColor(Block block, Vec rot) {} for (var rot: List.of( - new LineColor(Block.RED_CONCRETE, new Vec(dist, 0.1, 0.1)), + new LineColor(Block.RED_CONCRETE, new Vec(3, 0.1, 0.1)), new LineColor(Block.LIME_CONCRETE, new Vec(0.1, dist, 0.1)), - new LineColor(Block.LIGHT_BLUE_CONCRETE, new Vec(0.1, 0.1, dist)) + new LineColor(Block.LIGHT_BLUE_CONCRETE, new Vec(0.1, 0.1, 3)) )) { var entity = new DebugRendererEntity(EntityType.BLOCK_DISPLAY, "test"); var meta = (BlockDisplayMeta) entity.getEntityMeta(); - var normal = endPos.sub(startPos).asVec().normalize(); + var normal = Vec.fromPoint(endPos.sub(startPos)).normalize(); meta.setBlockState(rot.block()); meta.setScale(rot.rot()); - var defaultVector = new Vec(0, 1, 0); - - double t = defaultVector.dot(normal) / 2; - - double x = 1 - Math.cos(t); - meta.setLeftRotation(new Quaternion( - normal.x(), - normal.y(), - normal.z(), - n(normal.x()) - n(normal.y()) - n(normal.z()) - ).normalize().toFloatArray()); + meta.setLeftRotation(Quaternion.DEFAULT.rotate(normal).toFloatArray()); entity.setInstance(instance, startPos); } var line = new DebugLine("test", startPos, endPos, NamedTextColor.GOLD); line.setInstance(instance, startPos); } - - public static double n(double input) { - return Math.sqrt(1 - input * input); - } } diff --git a/api/src/main/java/ru/dragonestia/msb3/api/math/Quaternion.java b/api/src/main/java/ru/dragonestia/msb3/api/math/Quaternion.java index 051b905..3a010d7 100644 --- a/api/src/main/java/ru/dragonestia/msb3/api/math/Quaternion.java +++ b/api/src/main/java/ru/dragonestia/msb3/api/math/Quaternion.java @@ -1,5 +1,7 @@ package ru.dragonestia.msb3.api.math; +import net.minestom.server.coordinate.Vec; + public record Quaternion(double x, double y, double z, double w) { public static final Quaternion DEFAULT = new Quaternion(0, 0, 0, 1); @@ -16,4 +18,36 @@ public record Quaternion(double x, double y, double z, double w) { var length = length(); return new Quaternion(x / length, y / length, z / length, w / length); } + + public Quaternion conjugate() { + return new Quaternion(-x, -y, -z, w); + } + + public Quaternion mul(Quaternion target) { + return new Quaternion( + w() * target.x() + x() * target.w() + y() * target.z() - z() * target.y(), + w() * target.y() - x() * target.z() + y() * target.w() + z() * target.x(), + w() * target.z() + x() * target.y() - y() * target.x() + z() * target.w(), + w() * target.w() - x() * target.x() - y() * target.y() - z() * target.z() + ); + } + + public Quaternion rotate(Vec normal) { + var defaultQuaternion = new Quaternion(0, 0, 0, 1); + + var feta_x = Math.atan(normal.z()/normal.y()); + + var q0 = new Quaternion((Math.sin(feta_x / 2)), 0, 0, (Math.cos(feta_x / 2))); + var q = q0.mul(defaultQuaternion); + var localPos = new Quaternion(0, 1, 0, 0); + var qvq0 = q0.mul(localPos); + var qvq = qvq0.mul(q0.conjugate()); + var q_vector = new Vec(qvq.x(), qvq.y(), qvq.z()).normalize(); + + var multiply = normal.x() > q_vector.x() ? -1 : 1; + var feta_z = Math.acos(q_vector.dot(normal)); + + var q1 = new Quaternion(0, 0, multiply * (Math.sin(feta_z / 2)), (Math.cos(feta_z / 2))); + return q.mul(q1); + } }