import RapierBody from '@RE/RogueEngine/rogue-rapier/Components/RapierBody.re' import * as RE from 'rogue-engine' import * as THREE from 'three' import * as RAPIER from '@dimforge/rapier3d-compat' import RapierCollider from '@RE/RogueEngine/rogue-rapier/Components/Colliders/RapierCollider' import RapierConfig from '@RE/RogueEngine/rogue-rapier/Components/RapierConfig.re' export default class ObjectSpinner extends RE.Component { @RE.props.num() rotationSpeed = 1 @RE.props.vector3() rotationAxis = new THREE.Vector3(0,1,0) @RE.props.checkbox() useObjectUp = true rapierConfig: RapierConfig rapierBodyComponent: RapierBody rotation = 0 position = 1 awake() { } start() { this.rapierConfig = RE.getComponent(RapierConfig) as RapierConfig let allBodies = this.getRapierBodyComponentsFromChildren() if(allBodies.length > 0) { this.rapierBodyComponent = allBodies[0] } } getRapierBodyComponentsFromChildren() { let bodies: RapierBody[] = [] this.object3d.traverse(obj => { const components = RE.getObjectComponents(obj); components.forEach(comp => { if (comp instanceof RapierBody) { bodies.push(comp); } }); }); return bodies } update() { if(this.useObjectUp) { this.rotationAxis = this.object3d.up } if(this.rapierBodyComponent) { if (!this.rapierBodyComponent.body) { RE.Debug.logWarning("No character body") return } if (this.rapierBodyComponent.body.numColliders() < 1) { RE.Debug.logWarning("No character collider") return } const nextRotation = this.convertRapierToThree(this.rapierBodyComponent.body.rotation()) const newRotation = this.quaternionFromAxisAngle(this.rotationAxis, this.rotationSpeed / 1000) nextRotation.multiply(newRotation) this.rapierBodyComponent.body.setNextKinematicRotation(nextRotation) } else { this.object3d.rotateOnAxis(this.rotationAxis, this.rotationSpeed / 1000) } } convertRapierToThree(oldQuaternion: RAPIER.Quaternion) { return new THREE.Quaternion(oldQuaternion.x, oldQuaternion.y, oldQuaternion.z, oldQuaternion.w) } quaternionFromAxisAngle(axis, rotationRadians) { let factor = Math.sin(rotationRadians / 2) let x = axis.x * factor let y = axis.y * factor let z = axis.z * factor let w = Math.cos(rotationRadians / 2) let normalized = new THREE.Quaternion(x, y, z, w).normalize() return new THREE.Quaternion(normalized.x, normalized.y, normalized.z, normalized.w) } } RE.registerComponent(ObjectSpinner);