const DynObject = require("./dynObject");
const Centroid = require("./tools/centroid");
// Try to import matter-js as a commonJS module
var Matter;
if(typeof window === "object") {
Matter = window.Matter;
}
else {
Matter = require("matter-js");
}
/**
* Namespace of functions used to move objects in various ways.
* @memberof PhSim
* @namespace
*
*/
var Motion = {}
/**
*
* Apply force to a dynamic object.
* Force is ineffective against locked, semi-locked and permanetly static objects.
*
* @function
* @param {PhSim.DynObject} dynObject
* @param {Vector} position
* @param {Vector} forceVector
*
*/
Motion.applyForce = function(dynObject,position,forceVector) {
if(!dynObject.locked && !dynObject.noDyn) {
return Matter.Body.applyForce(dynObject.matter,position,forceVector);
}
}
/**
*
* Apply velocity to a dynamic object.
* Velocity does not effect locked, semi-locked objects or static objects.
*
* @function
* @param {PhSim.DynObject} dynObject
* @param {Vector} velocityVector
*/
Motion.setVelocity = function(dynObject,velocityVector) {
if(!dynObject.locked) {
return Matter.Body.setVelocity(dynObject.matter,velocityVector);
}
}
/**
*
* Apply a transformation to a dynamic object.
* Transformation does not move locked objects.
* However, it moves semi-locked objects and static objects.
*
* @function
* @param {PhSimObject} o
* @param {Vector} translationVector
*/
Motion.translate = function(o,translationVector) {
if(!o.locked) {
if(o.shape === "polygon") {
for(let i = 0; i < o.verts.length; i++) {
o.verts[i].x = o.verts[i].x + translationVector.x;
o.verts[i].y = o.verts[i].y + translationVector.y;
}
}
if(o.shape === "circle" || o.shape === "rectangle" || o.shape === "regPolygon") {
o.x = o.x + translationVector.x;
o.y = o.y + translationVector.y;
}
if(o instanceof DynObject) {
return Matter.Body.translate(o.matter,translationVector);
}
}
}
/**
* Apply a transformation to a dynamic object.
* Setting positions is ineffective against locked and permanetly static objects.
*
* @function
* @param {PhSim.DynObject} o
* @param {Vector} position
*/
Motion.setPosition = function(o,position) {
var c;
if(!o.locked) {
if(o.type === "circle" || o.type === "regPolygon") {
o.x = position.x;
o.y = position.y;
}
if(o.shape === "rectangle") {
c = Centroid.rectangle(o);
o.x = (o.x - c.x) + position.x;
o.y = (o.y - c.y) + position.y;
}
if(o.shape === "polygon") {
c = Centroid.polygon(o)
for(var i = 0; i < o.verts.length; i++) {
o.verts[i].x = (o.verts[i].x - c.x) + position.x;
o.verts[i].y = (o.verts[i].y - c.y) + position.y;
}
}
if(o instanceof DynObject) {
Matter.Body.setPosition(o.matter,position);
}
}
}
/**
* @function
* @param {PhSim.DynObject} dynObject
* @param {Number} angle
* @param {Vector} point
*/
Motion.rotate = function(dynObject,angle,point) {
if(!dynObject.locked) {
if(dynObject.skinmesh) {
Matter.Vertices.rotate(dynObject.skinmesh,angle,point);
}
return Matter.Body.rotate(dynObject.matter, angle, point)
}
}
/**
* Rotate dynamic object towards point
*
* @param {PhSim.DynObject} dynObject
* @param {Vector} point
*/
Motion.rotateTowards = function(dynObject,point) {
var a = Math.atan2(point.y - dynObject.matter.position.y ,point.x - dynObject.matter.position.x)
Motion.rotate(dynObject,a,dynObject.matter.position);
}
/**
* @function
* @param {PhSim.DynObject} dynObject
* @param {Number} angle
*/
Motion.setAngle = function(dynObject,angle) {
if(!dynObject.locked) {
if(dynObject.skinmesh) {
Matter.Vertices.rotate(dynObject.skinmesh,-dynObject.cycle,dynObject);
Matter.Vertices.rotate(dynObject.skinmesh,angle,dynObject);
}
return Matter.Body.setAngle(dynObject.matter,angle);
}
}
module.exports = Motion;