Source: physics/bodies/composite.js

import { Vector2 } from "../../math/index.js"
import { Component } from "../../ecs/index.js"
import { ObjType } from "../settings.js"

/**
 * Holds a group of related bodies and constraints.
 */
export class Composite extends Component {
  /**
   * Entity this belongs to.
   * 
   * @type Entity | null
   */
  entity = null
  /**
   * List of bodies contained.
   *
   * @type Body[]
   */
  bodies = []
  /**
   * List of bodies contained.
   *
   * @type Constraint[]
   */
  constraints = []
  /**
   * Used to determine what it is in a world.
   * 
   * @package
   * @type number 
   */
  get physicsType() {
    return ObjType.COMPOSITE
  }
  /**
   * Initializes the body to its given.Called by the world or an entity manager.
   * 
   * @param {Entity | null} entity
   * @param {boolean} composited
   */
  init(entity) {
    this.bodies.forEach(e => {
      e.init(entity, true)
    })
    this.requires(entity, "transform")

  }
  /**
   * @param {Constraint | Body} object
   */
  add(object) {
    if (object.physicsType === ObjType.CONSTRAINT)
      return this.constraints.push(object)
    if (object.physicsType === ObjType.BODY)
      this.bodies.push(object)
  }
  /**
   * This updates the world coordinates of shapes, anchors and bounds.
   */
  update() {
    this.lastPosition.copy(this.position)
  }
  /**
   * Acceleration of a body
   * 
   * @type Vector2
   */
  get acceleration() {
    let acceleration = new Vector2()
    for (var i = 0; i < this.bodies.length; i++) {
      acceleration.copy(this.bodies[i].acceleration)
    }
    return acceleration.divide(this.bodies.length)
  }
  set acceleration(x) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].acceleration = x
    }
  }
  /**
   * Velocity of a body
   * 
   * @type Vector2
   */
  get velocity() {
    let velocity = new Vector2()

    for (var i = 0; i < this.bodies.length; i++) {
      velocity.add(this.bodies[i].velocity)
    }
    return velocity.divide(this.bodies.length)
  }
  set velocity(x) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].velocity.copy(x)
    }
  }
  /**
   * Orientation of a body in degrees.
   * 
   * @type number
   */
  get angle() {
    let angle = 0
    for (var i = 0; i < this.bodies.length; i++) {
      angle += this.bodies[i].angle
    }
  }
  set angle(angle) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].angle = x
    }
  }

  /**
   * Mass of a body.
   * 
   * @type number
   */
  set mass(x) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].mass = x
    }
  }
  get mass() {
    let mass = 0
    for (var i = 0; i < this.bodies.length; i++) {
      mass += this.bodies[i].mass
    }
    return mass
  }
  set type(x) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].type = x
    }
  }
  get type() {
    return this.bodies[0]?.type
  }
  /**
   * Density of a body.
   * 
   * @type number
   */
  set density(x) {
    let area = 0
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].density = x
    }
  }
  get density() {
    let density = 0
    for (var i = 0; i < this.bodies.length; i++) {
      density += this.bodies[i].density
    }
    return density / this.bodies.length
  }
  /**
   * Position of a body
   * 
   * @type Vector2
   */
  get position() {
    let position = new Vector2()
    for (var i = 0; i < this.bodies.length; i++) {
      position.add(this.bodies[i].position)
    }
    return position
  }
  set position(x) {
    let dp = x.clone().sub(this.position)
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].position.add(dp)
    }
  }
  /**
   * Orientation of a body
   * 
   * @type Angle
   */
  set orientation(r) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].orientation.copy(r)
    }
  }
  get orientation() {
    let ang = 0
    for (var i = 0; i < this.bodies.length; i++) {
      ang += this.bodies[i].orientation
    }
    return ang / this.bodies.length
  }
  /**
   * Angular velocity of a body.
   * 
   * @type number
   */
  get angularVelocity() {
    let ang = 0
    for (var i = 0; i < this.bodies.length; i++) {
      ang += this.bodies[i].angularVelocity
    }
    return ang / this.bodies.length
  }
  set angularVelocity(x) {
    for (var i = 0; i < this.bodies.length; i++) {
      this.bodies[i].angularVelocity = x
    }
  }
  destroy() {
    this.bodies.forEach(b => {
      b.destroy()
    })
  }
}