ObjectSpinner.re.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import RapierBody from '@RE/RogueEngine/rogue-rapier/Components/RapierBody.re'
  2. import * as RE from 'rogue-engine'
  3. import * as THREE from 'three'
  4. import * as RAPIER from '@dimforge/rapier3d-compat'
  5. import RapierCollider from '@RE/RogueEngine/rogue-rapier/Components/Colliders/RapierCollider'
  6. import RapierConfig from '@RE/RogueEngine/rogue-rapier/Components/RapierConfig.re'
  7. export default class ObjectSpinner extends RE.Component {
  8. @RE.props.num() rotationSpeed = 1
  9. @RE.props.vector3() rotationAxis = new THREE.Vector3(0,1,0)
  10. @RE.props.checkbox() useObjectUp = true
  11. rapierConfig: RapierConfig
  12. rapierBodyComponent: RapierBody
  13. rotation = 0
  14. position = 1
  15. awake() {
  16. }
  17. start() {
  18. this.rapierConfig = RE.getComponent(RapierConfig) as RapierConfig
  19. let allBodies = this.getRapierBodyComponentsFromChildren()
  20. if(allBodies.length > 0) {
  21. this.rapierBodyComponent = allBodies[0]
  22. }
  23. }
  24. getRapierBodyComponentsFromChildren() {
  25. let bodies: RapierBody[] = []
  26. this.object3d.traverse(obj => {
  27. const components = RE.getObjectComponents(obj);
  28. components.forEach(comp => {
  29. if (comp instanceof RapierBody) {
  30. bodies.push(comp);
  31. }
  32. });
  33. });
  34. return bodies
  35. }
  36. update() {
  37. if(this.useObjectUp) {
  38. this.rotationAxis = this.object3d.up
  39. }
  40. if(this.rapierBodyComponent) {
  41. if (!this.rapierBodyComponent.body) {
  42. RE.Debug.logWarning("No character body")
  43. return
  44. }
  45. if (this.rapierBodyComponent.body.numColliders() < 1) {
  46. RE.Debug.logWarning("No character collider")
  47. return
  48. }
  49. const nextRotation = this.convertRapierToThree(this.rapierBodyComponent.body.rotation())
  50. const newRotation = this.quaternionFromAxisAngle(this.rotationAxis, this.rotationSpeed / 1000)
  51. nextRotation.multiply(newRotation)
  52. this.rapierBodyComponent.body.setNextKinematicRotation(nextRotation)
  53. } else {
  54. this.object3d.rotateOnAxis(this.rotationAxis, this.rotationSpeed / 1000)
  55. }
  56. }
  57. convertRapierToThree(oldQuaternion: RAPIER.Quaternion) {
  58. return new THREE.Quaternion(oldQuaternion.x, oldQuaternion.y, oldQuaternion.z, oldQuaternion.w)
  59. }
  60. quaternionFromAxisAngle(axis, rotationRadians) {
  61. let factor = Math.sin(rotationRadians / 2)
  62. let x = axis.x * factor
  63. let y = axis.y * factor
  64. let z = axis.z * factor
  65. let w = Math.cos(rotationRadians / 2)
  66. let normalized = new THREE.Quaternion(x, y, z, w).normalize()
  67. return new THREE.Quaternion(normalized.x, normalized.y, normalized.z, normalized.w)
  68. }
  69. }
  70. RE.registerComponent(ObjectSpinner);