diff --git a/demos/demos/transform/2d/lookat.js b/demos/demos/transform/2d/lookat.js index e462a3e8..000aecf4 100644 --- a/demos/demos/transform/2d/lookat.js +++ b/demos/demos/transform/2d/lookat.js @@ -95,7 +95,8 @@ function updateLookers(world) { target[0].x, target[0].y ) - + const offset = Rotary.fromAngle(-HALF_PI) + lookers.each(([orientation, transform]) => { const position = new Vector2( transform.x, @@ -105,9 +106,8 @@ function updateLookers(world) { // eslint-disable-next-line no-unused-vars const [_, finalOrientation] = lookAt.decompose() - const angle = Rotary.toAngle(finalOrientation) - orientation.value = angle - HALF_PI + orientation.copy(finalOrientation.multiply(offset)) }) } diff --git a/demos/demos/transform/2d/propagate.js b/demos/demos/transform/2d/propagate.js index 3a6df752..24cd89d4 100644 --- a/demos/demos/transform/2d/propagate.js +++ b/demos/demos/transform/2d/propagate.js @@ -18,7 +18,8 @@ import { without, has, PI, - QUARTER_PI + QUARTER_PI, + Rotary } from 'wima' import { addDefaultCamera2D } from '../../utils.js' @@ -85,7 +86,7 @@ function update(world) { if(!parent || !child || !grandChild) return - parent[0].value += QUARTER_PI * delta - child[0].value += QUARTER_PI * delta - grandChild[0].value += PI * delta + parent[0].multiply(Rotary.fromAngle(QUARTER_PI * delta)) + child[0].multiply(Rotary.fromAngle(QUARTER_PI * delta)) + grandChild[0].multiply(Rotary.fromAngle(PI * delta)) } \ No newline at end of file diff --git a/src/animation/core/animationeffector.js b/src/animation/core/animationeffector.js index bb5e8a40..6e575b3e 100644 --- a/src/animation/core/animationeffector.js +++ b/src/animation/core/animationeffector.js @@ -1,5 +1,6 @@ /** @import { Entity } from '../../ecs/index.js' */ import { World } from '../../ecs/registry.js' +import { Rotary } from '../../math/index.js' import { Position2D, Orientation2D, Scale2D, Position3D, Orientation3D, Scale3D } from '../../transform/index.js' /** @@ -65,7 +66,7 @@ export class Orientation2DAnimationEffector extends AnimationEffector { static apply(world, entity, results) { const component = world.get(entity, this.componentType) - component.value = results[0] + component.copy(Rotary.fromAngle(results[0])) } static elementSize() { return 1 diff --git a/src/integrator/systems/euler.js b/src/integrator/systems/euler.js index d790fa81..6c4117db 100644 --- a/src/integrator/systems/euler.js +++ b/src/integrator/systems/euler.js @@ -1,5 +1,5 @@ import { Query, World } from '../../ecs/index.js' -import { Quaternion, Vector2, Vector3 } from '../../math/index.js' +import { Quaternion, Rotary, Vector2, Vector3 } from '../../math/index.js' import { Acceleration2D, Acceleration3D, Rotation2D, Rotation3D, Torque2D, Torque3D, Velocity2D, Velocity3D } from '../../movable/index.js' import { Orientation2D, Orientation3D, Position2D, Position3D } from '../../transform/index.js' @@ -57,7 +57,9 @@ export function updateOrientationEuler2D(world) { const dt = 1 / 60 query.each(([orientation, rotation]) => { - orientation.value += rotation.value * dt + const angle = Rotary.fromAngle(rotation.value * dt) + + orientation.multiply(angle) }) } diff --git a/src/integrator/systems/verlet.js b/src/integrator/systems/verlet.js index c02ddba4..24572f7d 100644 --- a/src/integrator/systems/verlet.js +++ b/src/integrator/systems/verlet.js @@ -1,5 +1,5 @@ import { Query, World } from '../../ecs/index.js' -import { Vector2 } from '../../math/index.js' +import { Rotary, Vector2 } from '../../math/index.js' import { Acceleration2D, Rotation2D, Torque2D, Velocity2D } from '../../movable/index.js' import { Orientation2D, Position2D } from '../../transform/index.js' @@ -33,7 +33,7 @@ export function updateOrientationVerlet2D(world) { query.each(([orientation, rotation, torque]) => { torque.value *= dt * 0.5 rotation.value += torque.value - orientation.value += rotation.value * dt + torque.value * dt + orientation.multiply(Rotary.fromAngle(rotation.value * dt + torque.value * dt)) rotation.value += torque.value * dt * 0.5 torque.value = 0 }) diff --git a/src/math/core/angles/rotary.js b/src/math/core/angles/rotary.js index 377fbad3..fe6e8a4b 100644 --- a/src/math/core/angles/rotary.js +++ b/src/math/core/angles/rotary.js @@ -84,7 +84,7 @@ export class Rotary { * @returns {this} */ multiply(rotary) { - Rotary.multiply(rotary, this) + Rotary.multiply(rotary, this, this) return this } @@ -313,6 +313,23 @@ export class Rotary { return TAU - angle } + /** + * @param {Rotary} a + * @param {Rotary} b + * @param {number} t + * @param {Rotary} out + */ + static slerp(a, b, t, out = new Rotary()){ + const x = (a.cos + b.cos) * t + const y = (a.sin + b.sin) * t + const length = Math.sqrt(x * x + y * y) + + out.cos = x / length + out.sin = y / length + + return out + } + /** * @param {Rotary} rot1 * @param {Rotary} rot2 diff --git a/src/movable/prefabs/movable2d.js b/src/movable/prefabs/movable2d.js index 6eaa4b76..b0e9c9dc 100644 --- a/src/movable/prefabs/movable2d.js +++ b/src/movable/prefabs/movable2d.js @@ -1,4 +1,4 @@ -import { GlobalTransform2D, Orientation2D, Position2D, Scale2D } from '../../transform/index.js' +import { createTransform2D, GlobalTransform2D, Orientation2D, Position2D, Scale2D } from '../../transform/index.js' import { Velocity2D, Rotation2D, Acceleration2D, Torque2D } from '../components/index.js' /** @@ -8,7 +8,7 @@ import { Velocity2D, Rotation2D, Acceleration2D, Torque2D } from '../components/ * @returns {[Position2D, Orientation2D, Scale2D, GlobalTransform2D, Velocity2D, Rotation2D, Acceleration2D, Torque2D]} */ export function createMovable2D(x = 0, y = 0, a = 0) { - return [new Position2D(x, y), new Orientation2D(a), new Scale2D(), new GlobalTransform2D(), new Velocity2D(), new Rotation2D(), new Acceleration2D(), new Torque2D()] + return [...createTransform2D(x, y, a), new Velocity2D(), new Rotation2D(), new Acceleration2D(), new Torque2D()] } /** diff --git a/src/movable/prefabs/movable3d.js b/src/movable/prefabs/movable3d.js index f2b2669e..09a71961 100644 --- a/src/movable/prefabs/movable3d.js +++ b/src/movable/prefabs/movable3d.js @@ -1,11 +1,11 @@ -import { GlobalTransform3D, Orientation3D, Position3D, Scale3D } from '../../transform/index.js' +import { createTransform3D, GlobalTransform3D, Orientation3D, Position3D, Scale3D } from '../../transform/index.js' import { Velocity3D, Rotation3D, Acceleration3D, Torque3D } from '../components/index.js' /** * @returns {[Position3D,Orientation3D, Scale3D,GlobalTransform3D,Velocity3D,Rotation3D,Acceleration3D,Torque3D]} */ export function createMovable3D() { - return [new Position3D(), new Orientation3D(), new Scale3D(), new GlobalTransform3D(), new Velocity3D(), new Rotation3D(), new Acceleration3D(), new Torque3D()] + return [...createTransform3D(), new Velocity3D(), new Rotation3D(), new Acceleration3D(), new Torque3D()] } /** diff --git a/src/physics/systems/physics.js b/src/physics/systems/physics.js index c7dd9ff5..e6b762a3 100644 --- a/src/physics/systems/physics.js +++ b/src/physics/systems/physics.js @@ -4,6 +4,7 @@ import { CollisionManifold, Contacts } from '../../narrowphase/index.js' import { PhysicsSettings } from '../settings.js' import { Collider2D } from '../components/index.js' import { Orientation2D, Position2D, Scale2D } from '../../transform/index.js' +import { Rotary } from '../../math/index.js' /** * @param {World} world @@ -15,7 +16,7 @@ export function updateBodies(world) { Collider2D.update( shape, position, - orientation.value, + Rotary.toAngle(orientation), scale ) }) diff --git a/src/render-core/prefabs/camera2d.js b/src/render-core/prefabs/camera2d.js index d729281d..cb61a1a5 100644 --- a/src/render-core/prefabs/camera2d.js +++ b/src/render-core/prefabs/camera2d.js @@ -1,4 +1,4 @@ -import { GlobalTransform2D, Orientation2D, Position2D, Scale2D } from '../../transform/index.js' +import { createTransform2D, GlobalTransform2D, Orientation2D, Position2D, Scale2D } from '../../transform/index.js' import { Camera, RenderLists2D } from '../components/index.js' /** @@ -10,5 +10,5 @@ import { Camera, RenderLists2D } from '../components/index.js' * @returns {[Position2D,Orientation2D,Scale2D,GlobalTransform2D,Camera,RenderLists2D]} */ export function createCamera2D(x = 0, y = 0, a = 0, sx = 1, sy = 1) { - return [new Position2D(x, y), new Orientation2D(a), new Scale2D(sx, sy), new GlobalTransform2D(), new Camera(), new RenderLists2D()] + return [...createTransform2D(x, y, a, sx, sy), new Camera(), new RenderLists2D()] } \ No newline at end of file diff --git a/src/render-core/prefabs/camera3d.js b/src/render-core/prefabs/camera3d.js index 75e30eee..efd61965 100644 --- a/src/render-core/prefabs/camera3d.js +++ b/src/render-core/prefabs/camera3d.js @@ -1,5 +1,4 @@ -import { Quaternion } from '../../math/index.js' -import { Orientation3D, Position3D, Scale3D, GlobalTransform3D } from '../../transform/index.js' +import { Orientation3D, Position3D, Scale3D, GlobalTransform3D, createTransform3D } from '../../transform/index.js' import { Camera, RenderLists3D } from '../components/index.js' import { } from '../plugins/index.js' @@ -16,23 +15,18 @@ import { } from '../plugins/index.js' * @returns {[Position3D,Orientation3D,Scale3D,GlobalTransform3D,Camera,RenderLists3D]} */ export function createCamera3D( - x = 0, - y = 0, + x = 0, + y = 0, z = 0, - ox = 0, - oy = 0, + ox = 0, + oy = 0, oz = 0, - sx = 1, - sy = 1, + sx = 1, + sy = 1, sz = 1 ) { - const quaternion = Quaternion.fromEuler(ox, oy, oz) - return [ - new Position3D(x, y, z), - new Orientation3D().copy(quaternion), - new Scale3D(sx, sy, sz), - new GlobalTransform3D(), + ...createTransform3D(x, y, z, ox, oy, oz, sx, sy, sz), new Camera(), new RenderLists3D() ] diff --git a/src/transform/components/2d/orientation.js b/src/transform/components/2d/orientation.js index 77012b7d..12e54544 100644 --- a/src/transform/components/2d/orientation.js +++ b/src/transform/components/2d/orientation.js @@ -1,3 +1,3 @@ -import { Angle } from '../../../math/index.js' +import { Rotary } from '../../../math/index.js' -export class Orientation2D extends Angle{} \ No newline at end of file +export class Orientation2D extends Rotary {} \ No newline at end of file diff --git a/src/transform/prefabs/transform.js b/src/transform/prefabs/transform.js index 8642459a..43baa1ee 100644 --- a/src/transform/prefabs/transform.js +++ b/src/transform/prefabs/transform.js @@ -17,7 +17,7 @@ export function createTransform2D( ) { return [ new Position2D(dx, dy), - new Orientation2D(a), + new Orientation2D(Math.cos(a), Math.sin(a)), new Scale2D(sx, sy), new GlobalTransform2D() ] diff --git a/src/transform/systems/remote.js b/src/transform/systems/remote.js index ad921bec..620113a7 100644 --- a/src/transform/systems/remote.js +++ b/src/transform/systems/remote.js @@ -20,7 +20,7 @@ export function transformRemote2D(world) { position.copy(entity[0]).add(offPosition) } if (remote.copyOrientation) { - orientation.value = entity[1].value + Rotary.toAngle(offOrientation) + orientation.copy(Rotary.multiply(entity[1], offOrientation)) } if (remote.copyScale) { scale.copy(entity[2]).multiply(offScale) diff --git a/src/transform/systems/transform.js b/src/transform/systems/transform.js index 1686adbd..c0163a0b 100644 --- a/src/transform/systems/transform.js +++ b/src/transform/systems/transform.js @@ -1,6 +1,6 @@ import { Entity, has, Query, without, World } from '../../ecs/index.js' import { Children, Parent } from '../../hierarchy/index.js' -import { Affine2, Affine3, Rotary } from '../../math/index.js' +import { Affine2, Affine3 } from '../../math/index.js' import { RelationshipQuery } from '../../relationship/index.js' import { Position2D, Orientation2D, Scale2D, GlobalTransform2D, Position3D, Orientation3D, Scale3D, GlobalTransform3D } from '../components/index.js' @@ -11,7 +11,7 @@ export function synctransform2D(world) { const query = new Query(world, [Position2D, Orientation2D, Scale2D, GlobalTransform2D]) query.each(([position, orientation, scale, transform]) => { - transform.compose(position, Rotary.fromAngle(orientation.value), scale) + transform.compose(position, orientation, scale) }) } diff --git a/src/tween/plugin.js b/src/tween/plugin.js index e9bb4680..3004f61b 100644 --- a/src/tween/plugin.js +++ b/src/tween/plugin.js @@ -11,7 +11,7 @@ import { TweenRepeat, Tween } from './components/index.js' -import { Vector2, Quaternion, Vector3, Angle } from '../math/index.js' +import { Vector2, Quaternion, Vector3, Rotary } from '../math/index.js' import { generateTweenFlipSystem, generateTweenRepeatTween, generateTweenTimerSystem, generateTweenUpdateSystem } from './systems/index.js' import { Orientation2D, Orientation3D, Position2D, Position3D, Scale2D, Scale3D } from '../transform/index.js' import { typeidGeneric } from '../reflect/index.js' @@ -36,7 +36,7 @@ export class DefaultTweenPlugin extends Plugin { .registerPlugin(new TweenPlugin({ component: Orientation2D, tween: Orientation2DTween, - interpolation: Angle.lerp + interpolation: Rotary.slerp })) .registerPlugin(new TweenPlugin({ component: Orientation3D,