Repe [T3DU] and Moises Jpelaez updates

This commit is contained in:
2026-05-12 23:54:06 -07:00
parent 6b404f9da6
commit 39091e8db3
147 changed files with 5539 additions and 1750 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 = {

View File

@ -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;
}