forked from LeenkxTeam/LNXSDK
Repe [T3DU] and Moises Jpelaez updates
This commit is contained in:
@ -346,7 +346,7 @@ class KinematicCharacterController extends Trait {
|
||||
}
|
||||
}
|
||||
|
||||
@:enum abstract ControllerShape(Int) from Int to Int {
|
||||
enum abstract ControllerShape(Int) from Int to Int {
|
||||
var Box = 0;
|
||||
var Sphere = 1;
|
||||
var ConvexHull = 2;
|
||||
@ -355,7 +355,7 @@ class KinematicCharacterController extends Trait {
|
||||
var Capsule = 5;
|
||||
}
|
||||
|
||||
@:enum abstract ControllerActivationState(Int) from Int to Int {
|
||||
enum abstract ControllerActivationState(Int) from Int to Int {
|
||||
var Active = 1;
|
||||
var NoDeactivation = 4;
|
||||
var NoSimulation = 5;
|
||||
|
||||
@ -36,24 +36,24 @@ class PhysicsConstraint extends iron.Trait {
|
||||
|
||||
/**
|
||||
* Function to initialize physics constraint trait.
|
||||
*
|
||||
* @param object Pivot object to which this constraint trait will be added. The constraint limits are applied along the local axes of this object. This object need not
|
||||
* be a Rigid Body. Typically an `Empty` object may be used. Moving/rotating/parenting this pivot object has no effect once the constraint trait is added. Removing
|
||||
* the pivot object removes the constraint.
|
||||
*
|
||||
* @param body1 First rigid body to be constrained. This rigid body may be constrained by other constraints.
|
||||
*
|
||||
* @param body2 Second rigid body to be constrained. This rigid body may be constrained by other constraints.
|
||||
*
|
||||
* @param type Type of the constraint.
|
||||
*
|
||||
* @param disableCollisions Disable collisions between constrained objects.
|
||||
*
|
||||
* @param breakingThreshold Break the constraint if stress on this constraint exceeds this value. Set to 0 to make un-breakable.
|
||||
*
|
||||
* @param limits Constraint limits. This may be set before adding the trait to pivot object using the set limits functions.
|
||||
*
|
||||
**/
|
||||
*
|
||||
* @param object Pivot object to which this constraint trait will be added. The constraint limits are applied along the local axes of this object. This object need not
|
||||
* be a Rigid Body. Typically an `Empty` object may be used. Moving/rotating/parenting this pivot object has no effect once the constraint trait is added. Removing
|
||||
* the pivot object removes the constraint.
|
||||
*
|
||||
* @param body1 First rigid body to be constrained. This rigid body may be constrained by other constraints.
|
||||
*
|
||||
* @param body2 Second rigid body to be constrained. This rigid body may be constrained by other constraints.
|
||||
*
|
||||
* @param type Type of the constraint.
|
||||
*
|
||||
* @param disableCollisions Disable collisions between constrained objects.
|
||||
*
|
||||
* @param breakingThreshold Break the constraint if stress on this constraint exceeds this value. Set to 0 to make un-breakable.
|
||||
*
|
||||
* @param limits Constraint limits. This may be set before adding the trait to pivot object using the set limits functions.
|
||||
*
|
||||
**/
|
||||
public function new(body1: Object, body2: Object, type: ConstraintType, disableCollisions: Bool, breakingThreshold: Float, limits: Array<Float> = null) {
|
||||
super();
|
||||
|
||||
@ -335,7 +335,7 @@ class PhysicsConstraint extends iron.Trait {
|
||||
if (breakingThreshold > 0) con.setBreakingImpulseThreshold(breakingThreshold);
|
||||
|
||||
physics.addPhysicsConstraint(this);
|
||||
|
||||
|
||||
id = nextId;
|
||||
nextId++;
|
||||
|
||||
@ -350,11 +350,11 @@ class PhysicsConstraint extends iron.Trait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set constraint limits when using Hinge constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object
|
||||
**/
|
||||
* Function to set constraint limits when using Hinge constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object
|
||||
**/
|
||||
public function setHingeConstraintLimits(angLimit: Bool, lowerAngLimit: Float, upperAngLimit: Float) {
|
||||
|
||||
|
||||
angLimit? limits[0] = 1 : limits[0] = 0;
|
||||
|
||||
limits[1] = lowerAngLimit * (Math.PI/ 180);
|
||||
@ -362,11 +362,11 @@ class PhysicsConstraint extends iron.Trait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set constraint limits when using Slider constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object
|
||||
**/
|
||||
* Function to set constraint limits when using Slider constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object
|
||||
**/
|
||||
public function setSliderConstraintLimits(linLimit: Bool, lowerLinLimit: Float, upperLinLimit: Float) {
|
||||
|
||||
|
||||
linLimit? limits[0] = 1 : limits[0] = 0;
|
||||
|
||||
limits[1] = lowerLinLimit;
|
||||
@ -374,11 +374,11 @@ class PhysicsConstraint extends iron.Trait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set constraint limits when using Piston constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object
|
||||
**/
|
||||
* Function to set constraint limits when using Piston constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object
|
||||
**/
|
||||
public function setPistonConstraintLimits(linLimit: Bool, lowerLinLimit: Float, upperLinLimit: Float, angLimit: Bool, lowerAngLimit: Float, upperAngLimit: Float) {
|
||||
|
||||
|
||||
linLimit? limits[0] = 1 : limits[0] = 0;
|
||||
|
||||
limits[1] = lowerLinLimit;
|
||||
@ -391,9 +391,9 @@ class PhysicsConstraint extends iron.Trait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set customized constraint limits when using Generic/ Generic Spring constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object. Multiple constarints may be set by calling this function with different parameters.
|
||||
**/
|
||||
* Function to set customized constraint limits when using Generic/ Generic Spring constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object. Multiple constarints may be set by calling this function with different parameters.
|
||||
**/
|
||||
public function setGenericConstraintLimits(setLimit: Bool = false, lowerLimit: Float = 1.0, upperLimit: Float = -1.0, axis: ConstraintAxis = X, isAngular: Bool = false) {
|
||||
|
||||
var i = 0;
|
||||
@ -401,7 +401,7 @@ class PhysicsConstraint extends iron.Trait {
|
||||
var radian = (Math.PI/ 180);
|
||||
|
||||
switch (axis){
|
||||
case X:
|
||||
case X:
|
||||
i = 0;
|
||||
case Y:
|
||||
i = 3;
|
||||
@ -420,16 +420,16 @@ class PhysicsConstraint extends iron.Trait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set customized spring parameters when using Generic/ Generic Spring constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object. Multiple parameters to different axes may be set by calling this function with different parameters.
|
||||
**/
|
||||
* Function to set customized spring parameters when using Generic/ Generic Spring constraint. May be used after initalizing this trait but before adding it
|
||||
* to the pivot object. Multiple parameters to different axes may be set by calling this function with different parameters.
|
||||
**/
|
||||
public function setSpringParams(setSpring: Bool = false, stiffness: Float = 10.0, damping: Float = 0.5, axis: ConstraintAxis = X, isAngular: Bool = false) {
|
||||
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
|
||||
switch (axis){
|
||||
case X:
|
||||
case X:
|
||||
i = 18;
|
||||
case Y:
|
||||
i = 21;
|
||||
@ -453,10 +453,9 @@ class PhysicsConstraint extends iron.Trait {
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@:enum abstract ConstraintType(Int) from Int to Int {
|
||||
enum abstract ConstraintType(Int) from Int to Int {
|
||||
var Fixed = 0;
|
||||
var Point = 1;
|
||||
var Hinge = 2;
|
||||
@ -467,7 +466,7 @@ class PhysicsConstraint extends iron.Trait {
|
||||
var Motor = 7;
|
||||
}
|
||||
|
||||
@:enum abstract ConstraintAxis(Int) from Int to Int {
|
||||
enum abstract ConstraintAxis(Int) from Int to Int {
|
||||
var X = 0;
|
||||
var Y = 1;
|
||||
var Z = 2;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package leenkx.trait.physics.bullet;
|
||||
|
||||
#if lnx_bullet
|
||||
|
||||
import iron.Trait;
|
||||
import iron.system.Time;
|
||||
import iron.math.Vec4;
|
||||
@ -10,7 +9,6 @@ import iron.math.RayCaster;
|
||||
import leenkx.trait.physics.PhysicsCache;
|
||||
|
||||
class Hit {
|
||||
|
||||
public var rb: RigidBody;
|
||||
public var pos: Vec4;
|
||||
public var normal: Vec4;
|
||||
@ -33,7 +31,6 @@ class ConvexHit {
|
||||
}
|
||||
|
||||
class ContactPair {
|
||||
|
||||
public var a: Int;
|
||||
public var b: Int;
|
||||
public var posA: Vec4;
|
||||
@ -48,7 +45,6 @@ class ContactPair {
|
||||
}
|
||||
|
||||
class PhysicsWorld extends Trait {
|
||||
|
||||
public static var active: PhysicsWorld = null;
|
||||
static var sceneRemoved = false;
|
||||
|
||||
@ -207,6 +203,12 @@ class PhysicsWorld extends Trait {
|
||||
rbMap.set(body.id, body);
|
||||
}
|
||||
|
||||
public function updateRigidBody(body: RigidBody) {
|
||||
if (world != null) world.removeRigidBody(body.body);
|
||||
rbMap.remove(body.id);
|
||||
addRigidBody(body);
|
||||
}
|
||||
|
||||
public function addPhysicsConstraint(constraint: PhysicsConstraint) {
|
||||
world.addConstraint(constraint.con, constraint.disableCollisions);
|
||||
conMap.set(constraint.id, constraint);
|
||||
@ -319,7 +321,7 @@ class PhysicsWorld extends Trait {
|
||||
world.stepSimulation(t, currMaxSteps, Time.fixedStep);
|
||||
updateContacts();
|
||||
|
||||
for (rb in rbMap) @:privateAccess rb.physicsUpdate();
|
||||
for (rb in rbMap) { @:privateAccess try { rb.physicsUpdate(); } catch(e:haxe.Exception) { trace(e.message); } } // HACK: see this recommendation: https://github.com/armory3d/armory/issues/3044#issuecomment-2558199944.
|
||||
|
||||
#if lnx_debug
|
||||
physTime = kha.Scheduler.realTime() - startTime;
|
||||
|
||||
@ -68,6 +68,10 @@ class RigidBody extends iron.Trait {
|
||||
public var onReady: Void->Void = null;
|
||||
public var onContact: Array<RigidBody->Void> = null;
|
||||
public var heightData: haxe.io.Bytes = null;
|
||||
|
||||
// Compound shape children (baked from exporter)
|
||||
var compoundChildren: Array<CompoundChild> = null;
|
||||
|
||||
#if js
|
||||
static var ammoArray: Int = -1;
|
||||
#end
|
||||
@ -92,7 +96,6 @@ class RigidBody extends iron.Trait {
|
||||
|
||||
// Interpolation
|
||||
var interpolate: Bool = false;
|
||||
var time: Float = 0.0;
|
||||
var currentPos: bullet.Bt.Vector3 = new bullet.Bt.Vector3(0, 0, 0);
|
||||
var prevPos: bullet.Bt.Vector3 = new bullet.Bt.Vector3(0, 0, 0);
|
||||
var currentRot: bullet.Bt.Quaternion = new bullet.Bt.Quaternion(0, 0, 0, 1);
|
||||
@ -131,7 +134,7 @@ class RigidBody extends iron.Trait {
|
||||
angularFactorsZ: 1.0,
|
||||
collisionMargin: 0.0,
|
||||
linearDeactivationThreshold: 0.0,
|
||||
angularDeactivationThrshold: 0.0,
|
||||
angularDeactivationThreshold: 0.0,
|
||||
deactivationTime: 0.0,
|
||||
linearVelocityMin: 0.0,
|
||||
linearVelocityMax: 0.0,
|
||||
@ -160,7 +163,7 @@ class RigidBody extends iron.Trait {
|
||||
this.linearFactors = [params.linearFactorsX, params.linearFactorsY, params.linearFactorsZ];
|
||||
this.angularFactors = [params.angularFactorsX, params.angularFactorsY, params.angularFactorsZ];
|
||||
this.collisionMargin = params.collisionMargin;
|
||||
this.deactivationParams = [params.linearDeactivationThreshold, params.angularDeactivationThrshold, params.deactivationTime];
|
||||
this.deactivationParams = [params.linearDeactivationThreshold, params.angularDeactivationThreshold, params.deactivationTime];
|
||||
// New velocity limiting properties
|
||||
this.linearVelocityMin = params.linearVelocityMin;
|
||||
this.linearVelocityMax = params.linearVelocityMax;
|
||||
@ -180,6 +183,9 @@ class RigidBody extends iron.Trait {
|
||||
this.staticObj = flags.staticObj;
|
||||
this.useDeactivation = flags.useDeactivation;
|
||||
|
||||
// Store compound children data if provided
|
||||
this.compoundChildren = params.compoundChildren;
|
||||
|
||||
notifyOnAdd(init);
|
||||
}
|
||||
|
||||
@ -281,6 +287,25 @@ class RigidBody extends iron.Trait {
|
||||
btshape.setLocalScaling(vec1);
|
||||
#end
|
||||
}
|
||||
else if (shape == Shape.Compound) {
|
||||
// Create compound shape and add all child shapes
|
||||
var compound = new bullet.Bt.CompoundShape(true);
|
||||
if (compoundChildren != null) {
|
||||
for (child in compoundChildren) {
|
||||
var childShape = createChildShape(child);
|
||||
if (childShape != null) {
|
||||
// Set child local transform
|
||||
trans2.setIdentity();
|
||||
vec1.setValue(child.posX, child.posY, child.posZ);
|
||||
trans2.setOrigin(vec1);
|
||||
quat1.setValue(child.rotX, child.rotY, child.rotZ, child.rotW);
|
||||
trans2.setRotation(quat1);
|
||||
compound.addChildShape(trans2, childShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
btshape = compound;
|
||||
}
|
||||
|
||||
trans1.setIdentity();
|
||||
vec1.setX(transform.worldx());
|
||||
@ -313,7 +338,7 @@ class RigidBody extends iron.Trait {
|
||||
bodyColl.setRollingFriction(angularFriction);
|
||||
bodyColl.setRestitution(restitution);
|
||||
|
||||
if ( useDeactivation) {
|
||||
if (useDeactivation) {
|
||||
setDeactivationParams(deactivationParams[0], deactivationParams[1], deactivationParams[2]);
|
||||
}
|
||||
else {
|
||||
@ -382,16 +407,49 @@ class RigidBody extends iron.Trait {
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a child collision shape for compound rigidbodies from baked export data.
|
||||
* @param child The compound child data containing shape type and dimensions
|
||||
* @return The created Bullet collision shape, or null if shape type is unsupported
|
||||
*/
|
||||
function createChildShape(child: CompoundChild): bullet.Bt.CollisionShape {
|
||||
var childShapeType: Int = child.shape;
|
||||
|
||||
if (childShapeType == Shape.Box) {
|
||||
vec1.setValue(withMargin(child.dimX / 2), withMargin(child.dimY / 2), withMargin(child.dimZ / 2));
|
||||
return new bullet.Bt.BoxShape(vec1);
|
||||
}
|
||||
else if (childShapeType == Shape.Sphere) {
|
||||
return new bullet.Bt.SphereShape(withMargin(child.dimX / 2));
|
||||
}
|
||||
else if (childShapeType == Shape.Cone) {
|
||||
var coneZ = new bullet.Bt.ConeShapeZ(
|
||||
withMargin(child.dimX / 2), // Radius
|
||||
withMargin(child.dimZ)); // Height
|
||||
return coneZ;
|
||||
}
|
||||
else if (childShapeType == Shape.Cylinder) {
|
||||
vec1.setValue(withMargin(child.dimX / 2), withMargin(child.dimY / 2), withMargin(child.dimZ / 2));
|
||||
var cylZ = new bullet.Bt.CylinderShapeZ(vec1);
|
||||
return cylZ;
|
||||
}
|
||||
else if (childShapeType == Shape.Capsule) {
|
||||
var r = child.dimX / 2;
|
||||
var capsZ = new bullet.Bt.CapsuleShapeZ(
|
||||
withMargin(r), // Radius
|
||||
withMargin(child.dimZ - r * 2)); // Height between 2 sphere centers
|
||||
return capsZ;
|
||||
}
|
||||
else {
|
||||
// Unsupported shape type for compound children (ConvexHull, Mesh, Terrain)
|
||||
trace("Warning: Unsupported compound child shape type: " + childShapeType);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (interpolate) {
|
||||
time += Time.delta;
|
||||
|
||||
while (time >= Time.fixedStep) {
|
||||
time -= Time.fixedStep;
|
||||
}
|
||||
|
||||
var t: Float = time / Time.fixedStep;
|
||||
var t: Float = Time.fixedStepInterpolation;
|
||||
t = Helper.clamp(t, 0, 1);
|
||||
|
||||
var tx: Float = prevPos.x() * (1.0 - t) + currentPos.x() * t;
|
||||
@ -402,9 +460,6 @@ class RigidBody extends iron.Trait {
|
||||
|
||||
transform.loc.set(tx, ty, tz, 1.0);
|
||||
transform.rot.set(tRot.x(), tRot.y(), tRot.z(), tRot.w());
|
||||
} else {
|
||||
transform.loc.set(currentPos.x(), currentPos.y(), currentPos.z(), 1.0);
|
||||
transform.rot.set(currentRot.x(), currentRot.y(), currentRot.z(), currentRot.w());
|
||||
}
|
||||
|
||||
if (object.parent != null) {
|
||||
@ -429,32 +484,30 @@ class RigidBody extends iron.Trait {
|
||||
var len = Math.sqrt(x * x + y * y + z * z + w * w);
|
||||
return new bullet.Bt.Quaternion(x / len, y / len, z / len, w / len);
|
||||
}
|
||||
|
||||
|
||||
function physicsUpdate() {
|
||||
if (!ready) return;
|
||||
|
||||
prevPos.setValue(currentPos.x(), currentPos.y(), currentPos.z());
|
||||
prevRot.setValue(currentRot.x(), currentRot.y(), currentRot.z(), currentRot.w());
|
||||
|
||||
if (animated) {
|
||||
syncTransform();
|
||||
} else {
|
||||
if (interpolate) {
|
||||
prevPos.setValue(currentPos.x(), currentPos.y(), currentPos.z());
|
||||
prevRot.setValue(currentRot.x(), currentRot.y(), currentRot.z(), currentRot.w());
|
||||
}
|
||||
var trans = body.getWorldTransform();
|
||||
var p = trans.getOrigin();
|
||||
var q = trans.getRotation();
|
||||
transform.clearDelta();
|
||||
// transform.buildMatrix();
|
||||
currentPos.setValue(p.x(), p.y(), p.z());
|
||||
currentRot.setValue(q.x(), q.y(), q.z(), q.w());
|
||||
|
||||
|
||||
#if hl
|
||||
p.delete();
|
||||
q.delete();
|
||||
trans.delete();
|
||||
#end
|
||||
}
|
||||
|
||||
var trans = body.getWorldTransform();
|
||||
var p = trans.getOrigin();
|
||||
var q = trans.getRotation();
|
||||
|
||||
currentPos.setValue(p.x(), p.y(), p.z());
|
||||
currentRot.setValue(q.x(), q.y(), q.z(), q.w());
|
||||
|
||||
#if hl
|
||||
p.delete();
|
||||
q.delete();
|
||||
trans.delete();
|
||||
#end
|
||||
|
||||
if (onContact != null) {
|
||||
var rbs = physics.getContacts(this);
|
||||
if (rbs != null) for (rb in rbs) for (f in onContact) f(rb);
|
||||
@ -533,6 +586,18 @@ class RigidBody extends iron.Trait {
|
||||
bodyColl.activate(false);
|
||||
}
|
||||
|
||||
public function setGroup(group: Int) {
|
||||
if (this.group == group) return;
|
||||
this.group = group;
|
||||
physics.updateRigidBody(this);
|
||||
}
|
||||
|
||||
public function setMask(mask: Int) {
|
||||
if (this.mask == mask) return;
|
||||
this.mask = mask;
|
||||
physics.updateRigidBody(this);
|
||||
}
|
||||
|
||||
public function disableGravity() {
|
||||
vec1.setValue(0, 0, 0);
|
||||
body.setGravity(vec1);
|
||||
@ -817,7 +882,7 @@ class RigidBody extends iron.Trait {
|
||||
}
|
||||
}
|
||||
|
||||
@:enum abstract Shape(Int) from Int to Int {
|
||||
enum abstract Shape(Int) from Int to Int {
|
||||
var Box = 0;
|
||||
var Sphere = 1;
|
||||
var ConvexHull = 2;
|
||||
@ -826,6 +891,7 @@ class RigidBody extends iron.Trait {
|
||||
var Cylinder = 5;
|
||||
var Capsule = 6;
|
||||
var Terrain = 7;
|
||||
var Compound = 8;
|
||||
}
|
||||
|
||||
typedef RigidBodyParams = {
|
||||
@ -840,7 +906,7 @@ typedef RigidBodyParams = {
|
||||
var angularFactorsZ: Float;
|
||||
var collisionMargin: Float;
|
||||
var linearDeactivationThreshold: Float;
|
||||
var angularDeactivationThrshold: Float;
|
||||
var angularDeactivationThreshold: Float;
|
||||
var deactivationTime: Float;
|
||||
var linearVelocityMin: Float;
|
||||
var linearVelocityMax: Float;
|
||||
@ -852,6 +918,21 @@ typedef RigidBodyParams = {
|
||||
var lockRotationX: Bool;
|
||||
var lockRotationY: Bool;
|
||||
var lockRotationZ: Bool;
|
||||
@:optional var compoundChildren: Array<CompoundChild>;
|
||||
}
|
||||
|
||||
typedef CompoundChild = {
|
||||
var shape: Int; // 0=Box, 1=Sphere, 2=ConvexHull, 3=Mesh, 4=Cone, 5=Cylinder, 6=Capsule
|
||||
var posX: Float; // Local position relative to parent
|
||||
var posY: Float;
|
||||
var posZ: Float;
|
||||
var rotX: Float; // Local rotation quaternion
|
||||
var rotY: Float;
|
||||
var rotZ: Float;
|
||||
var rotW: Float;
|
||||
var dimX: Float; // Dimensions
|
||||
var dimY: Float;
|
||||
var dimZ: Float;
|
||||
}
|
||||
|
||||
typedef RigidBodyFlags = {
|
||||
|
||||
@ -297,7 +297,7 @@ class SoftBody extends Trait {
|
||||
vertOffsetX /= numNodes;
|
||||
vertOffsetY /= numNodes;
|
||||
vertOffsetZ /= numNodes;
|
||||
|
||||
|
||||
//Setting the mean position as object local location
|
||||
mo.transform.scale.set(1, 1, 1);
|
||||
mo.transform.loc.set(vertOffsetX, vertOffsetY, vertOffsetZ);
|
||||
@ -343,7 +343,7 @@ class SoftBody extends Trait {
|
||||
var mx = nodePos.x() - vertOffsetX;
|
||||
var my = nodePos.y() - vertOffsetY;
|
||||
var mz = nodePos.z() - vertOffsetZ;
|
||||
|
||||
|
||||
var nx = nodeNor.x();
|
||||
var ny = nodeNor.y();
|
||||
var nz = nodeNor.z();
|
||||
@ -423,7 +423,7 @@ class SoftBody extends Trait {
|
||||
#end
|
||||
}
|
||||
|
||||
@:enum abstract SoftShape(Int) from Int {
|
||||
enum abstract SoftShape(Int) from Int {
|
||||
var Cloth = 0;
|
||||
var Volume = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user