@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
190 lines (189 loc) • 6.87 kB
JavaScript
"use strict";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { InputCloneMode } from "../../poly/InputCloneMode";
import { SopType } from "../../poly/registers/nodes/types/Sop";
import { CorePhysicsAttribute, PhysicsRBDColliderType, PhysicsRBDType } from "../../../core/physics/PhysicsAttribute";
import { PhysicsPlayerType } from "../../../core/physics/player/PhysicsPlayer";
import { SphereBuilder } from "../../../core/geometry/builders/SphereBuilder";
import { ObjectType } from "../../../core/geometry/Constant";
import { CorePath } from "../../../core/geometry/CorePath";
import { BaseSopOperation } from "../../operations/sop/_Base";
import { Vector3 } from "three";
import { TypedActorSopNode } from "./_BaseActor";
const DEFAULT = {
radius: 0.5,
density: 5,
//1000,
friction: 1,
//0.5,
restitution: 0.5,
linearDamping: 0.4,
//0,
angularDamping: 10,
linearVelocity: new Vector3(0, 0, 0),
angularVelocity: new Vector3(0, 0, 0),
gravityScale: 1
};
const type = PhysicsPlayerType.TORQUE;
class PhysicsPlayerSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
this.main = ParamConfig.FOLDER();
/** @param radius */
this.radius = ParamConfig.FLOAT(0.5, {
range: [0, 2],
rangeLocked: [true, false]
});
/** @param density */
this.density = ParamConfig.FLOAT(DEFAULT.density, {
range: [0, 100],
rangeLocked: [true, false],
separatorBefore: true
});
/** @param friction */
this.friction = ParamConfig.FLOAT(DEFAULT.friction, {
range: [0, 1],
rangeLocked: [true, false]
});
/** @param restitution */
this.restitution = ParamConfig.FLOAT(DEFAULT.restitution, {
range: [0, 2],
rangeLocked: [true, false]
});
/** @param linear damping (affects velocity) */
this.linearDamping = ParamConfig.FLOAT(DEFAULT.linearDamping, {
range: [0, 10],
rangeLocked: [true, false]
});
/** @param angular damping (affects rotations) */
this.angularDamping = ParamConfig.FLOAT(DEFAULT.angularDamping, {
range: [0, 10],
rangeLocked: [true, false]
});
/** @param linear velocity */
this.linearVelocity = ParamConfig.VECTOR3(DEFAULT.linearVelocity);
/** @param angular velocity */
this.angularVelocity = ParamConfig.VECTOR3(DEFAULT.angularVelocity);
/** @param gravity Scale */
this.gravityScale = ParamConfig.FLOAT(DEFAULT.gravityScale, {
range: [-10, 10],
rangeLocked: [false, false]
});
this.details = ParamConfig.FOLDER();
/** @param id */
this.id = ParamConfig.STRING("`$OS`");
}
/** @param collision offset */
// offset = ParamConfig.FLOAT(0.02, {
// range: [0, 0.1],
// rangeLocked: [true, false],
// });
// /** @param apply impulses */
// applyImpulses = ParamConfig.BOOLEAN(1);
// /** @param distance below which the player will be snapped to the ground */
// snapToGroundDistance = ParamConfig.FLOAT(0.5, {
// range: [0, 1],
// rangeLocked: [true, false],
// });
// /** @param auto step */
// autoStep = ParamConfig.BOOLEAN(1, {
// separatorBefore: true,
// });
// /** @param auto step max height */
// autoStepMaxHeight = ParamConfig.FLOAT(0.5, {
// range: [0, 1],
// rangeLocked: [true, false],
// visibleIf: {autoStep: 1},
// });
// /** @param auto step max height */
// autoStepMinWidth = ParamConfig.FLOAT(0.5, {
// range: [0, 1],
// rangeLocked: [true, false],
// visibleIf: {autoStep: 1},
// });
// /** @param auto step on dynamic objects */
// autoStepOnDynamic = ParamConfig.BOOLEAN(1, {
// visibleIf: {autoStep: 1},
// });
// /** @param Don’t allow climbing slopes larger than this angle */
// maxSlopeClimbAngle = ParamConfig.FLOAT(45, {
// separatorBefore: true,
// range: [0, 90],
// rangeLocked: [true, true],
// });
// /** @param Automatically slide down on slopes smaller than this angle */
// minSlopeSlideAngle = ParamConfig.FLOAT(30, {
// range: [0, 90],
// rangeLocked: [true, true],
// });
// /** @param up vector used in slope angle calculations */
// up = ParamConfig.VECTOR3([0, 1, 0]);
}
const ParamsConfig = new PhysicsPlayerSopParamsConfig();
export class PhysicsPlayerSopNode extends TypedActorSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
}
static type() {
return SopType.PHYSICS_PLAYER;
}
initializeNode() {
this.io.inputs.setCount(0, 2);
this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE);
}
cook(inputCoreGroups) {
this.compilationController.compileIfRequired();
const coreGroup0 = inputCoreGroups[0];
const coreGroup1 = inputCoreGroups[1];
const inputObjects = coreGroup0 ? coreGroup0.threejsObjects() : this._createDefaultInputObjects();
const playerObject = inputObjects[0];
this._updatePlayerObject(playerObject);
const objects = [playerObject];
if (coreGroup1) {
const cameraObject = coreGroup1.threejsObjects()[0];
if (cameraObject) {
objects.push(cameraObject);
const cameraPath = CorePath.objectPath(cameraObject);
CorePhysicsAttribute.setCharacterControllerCameraPath(playerObject, cameraPath);
}
}
this.setObjects(objects);
}
_updatePlayerObject(object) {
const actorNode = this._findActorNode();
this.scene().actorsManager.assignActorBuilder(object, actorNode);
CorePhysicsAttribute.setRBDType(
object,
type == PhysicsPlayerType.TORQUE ? PhysicsRBDType.DYNAMIC : PhysicsRBDType.KINEMATIC_POS
);
CorePhysicsAttribute.setColliderType(object, PhysicsRBDColliderType.SPHERE);
CorePhysicsAttribute.setRadius(object, this.pv.radius);
const rbdId = this.pv.id;
object.name = rbdId;
CorePhysicsAttribute.setRBDId(object, rbdId);
CorePhysicsAttribute.setCharacterControllerId(object, rbdId);
CorePhysicsAttribute.setDensity(object, this.pv.density);
CorePhysicsAttribute.setFriction(object, this.pv.friction);
CorePhysicsAttribute.setRestitution(object, this.pv.restitution);
CorePhysicsAttribute.setLinearDamping(object, this.pv.linearDamping);
CorePhysicsAttribute.setAngularDamping(object, this.pv.angularDamping);
CorePhysicsAttribute.setLinearVelocity(object, this.pv.linearVelocity);
CorePhysicsAttribute.setAngularVelocity(object, this.pv.angularVelocity);
CorePhysicsAttribute.setGravityScale(object, this.pv.gravityScale);
}
_createDefaultInputObjects() {
const geometry = SphereBuilder.create({
radius: this.pv.radius,
widthSegments: 30,
heightSegments: 30,
asLines: false,
open: false
});
const object = BaseSopOperation.createObject(geometry, ObjectType.MESH);
return [object];
}
_findActorNode() {
return this;
}
}