Guide hace 6 años
padre
commit
240b59d251

+ 1 - 0
src/Physics/IPhysicsEngine.ts

@@ -52,6 +52,7 @@ export interface IPhysicsEnginePlugin {
     setBodyVelocityIterations?(impostor: PhysicsImpostor, velocityIterations: number): void;
     getBodyPositionIterations?(impostor: PhysicsImpostor): number;
     setBodyPositionIterations?(impostor: PhysicsImpostor, positionIterations: number): void;
+    appendAnchor?(impostor: PhysicsImpostor, otherImpostor: PhysicsImpostor, width: number, height: number, influence: number, noCollisionBetweenLinkedBodies: boolean): void;
     sleepBody(impostor: PhysicsImpostor): void;
     wakeUpBody(impostor: PhysicsImpostor): void;
     raycast(from: Vector3, to: Vector3): PhysicsRaycastResult;

+ 29 - 6
src/Physics/Plugins/ammoJSPlugin.ts

@@ -223,6 +223,10 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
      * @param impostor imposter to match
      */
     public afterSoftStep(impostor: PhysicsImpostor): void {
+        var multiplier = 1;
+        if (impostor.type === PhysicsImpostor.SoftbodyImpostor) {
+            multiplier = -1;
+        }
         var object = impostor.object;
         var vertexPositions = object.getVerticesData(VertexBuffer.PositionKind);
         if (!vertexPositions) {
@@ -245,11 +249,11 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
             nodePositions = node.get_m_x();
             x = nodePositions.x();
             y = nodePositions.y();
-            z = -nodePositions.z();
+            z = multiplier * nodePositions.z();
             var nodeNormals = node.get_m_n();
             nx = nodeNormals.x();
             ny = nodeNormals.y();
-            nz = -nodeNormals.z();
+            nz = multiplier * nodeNormals.z();
 
             vertexPositions[3 * n] = x;
             vertexPositions[3 * n + 1] = y;
@@ -654,10 +658,10 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
                 var segments = Math.sqrt(len / 3);
                 impostor.segments = segments - 1;
                 var segs = segments - 1;
-                this._tmpAmmoVectorA.setValue(vertexPositions[0], vertexPositions[1], -vertexPositions[2]);
-                this._tmpAmmoVectorB.setValue(vertexPositions[3 * segs], vertexPositions[3 * segs + 1], -vertexPositions[3 * segs + 2]);
-                this._tmpAmmoVectorD.setValue(vertexPositions[len - 3], vertexPositions[len - 2], -vertexPositions[len - 1]);
-                this._tmpAmmoVectorC.setValue(vertexPositions[len - 3 - 3 * segs], vertexPositions[len - 2 - 3 * segs], -vertexPositions[len - 1 - 3 * segs]);
+                this._tmpAmmoVectorA.setValue(vertexPositions[0], vertexPositions[1], vertexPositions[2]);
+                this._tmpAmmoVectorB.setValue(vertexPositions[3 * segs], vertexPositions[3 * segs + 1], vertexPositions[3 * segs + 2]);
+                this._tmpAmmoVectorD.setValue(vertexPositions[len - 3], vertexPositions[len - 2], vertexPositions[len - 1]);
+                this._tmpAmmoVectorC.setValue(vertexPositions[len - 3 - 3 * segs], vertexPositions[len - 2 - 3 * segs], vertexPositions[len - 1 - 3 * segs]);
 
                 var clothBody = new Ammo.btSoftBodyHelpers().CreatePatch(
                     this.world.getWorldInfo(),
@@ -670,6 +674,7 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
                     impostor.getParam("fixedPoints"),
                     true
                 );
+                clothBody.get_m_cfg().set_collisions(0x11);
                 return clothBody;
             }
         }
@@ -1145,6 +1150,24 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
         }
     }
 
+     /**
+     * Append an anchor to a soft object
+     * @param impostor, soft impostor to add anchor to
+     * @param otherImpostor, rigid impostor as the anchor
+     * @param width, ratio across width from 0 to 1
+     * @param height, ratio up height from 0 to 1
+     * @param influenece, the elasticity between soft impostor and anchor from 0, very stretchy to 1, no strech
+     * @param noCollisionBetweenLinkedBodies, when true collisions between soft impostor and anchor are ignored; default false
+     */
+    public appendAnchor(impostor: PhysicsImpostor, otherImpostor: PhysicsImpostor, width: number, height: number, influence: number = 1, noCollisionBetweenLinkedBodies: boolean = false) {
+        var segs = impostor.segments;
+        var nbAcross = Math.round(segs * width);
+        var nbUp = Math.round(segs * height);
+        var nbDown = segs - nbUp;
+        var node = nbAcross + segs * nbDown;
+        impostor.physicsBody.appendAnchor(node, otherImpostor.physicsBody, noCollisionBetweenLinkedBodies, influence);
+    }
+
     /**
      * Sleeps the physics body and stops it from being active
      * @param impostor impostor to sleep

+ 23 - 0
src/Physics/physicsImpostor.ts

@@ -948,6 +948,29 @@ export class PhysicsImpostor {
     }
 
     /**
+     * Add an anchor to a soft impostor
+     * @param otherImpostor, rigid impostor as the anchor
+     * @param noCollisionBetweenLinkedBodies, when true collisions between soft impostor and anchor are ignored; default false
+     * @param influenece, the elasticity between soft impostor and anchor from 0, very stretchy to 1, no strech.
+     * @param width, ratio across width from 0 to 1
+     * @param height, ratio up height from 0 to 1
+     * @returns the soft imposter
+     */
+    public addAnchor(otherImpostor: PhysicsImpostor, width: number, height: number, influence: number, noCollisionBetweenLinkedBodies: boolean): PhysicsImpostor {
+        if (!this._physicsEngine) {
+            return this;
+        }
+        const plugin = this._physicsEngine.getPhysicsPlugin();
+        if (!plugin.appendAnchor) {
+            return this;
+        }
+        if (this._physicsEngine) {
+            plugin.appendAnchor!(this, otherImpostor, width, height, influence, noCollisionBetweenLinkedBodies);
+        }
+        return this;
+    }
+
+    /**
      * Will keep this body still, in a sleep mode.
      * @returns the physics imposter
      */