Explorar o código

Merge pull request #5975 from BabylonJSGuide/master

Anchoring a Cloth
David Catuhe %!s(int64=6) %!d(string=hai) anos
pai
achega
aa5f698b23

+ 2 - 2
dist/preview release/what's new.md

@@ -6,8 +6,8 @@
 - Added support for [parallel shader compilation](https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/) ([Deltakosh](https://github.com/deltakosh))
 - Added [Object Based Motion Blur](http://doc.babylonjs.com/how_to/using_motionblurpostprocess) post-process ([julien-moreau](https://github.com/julien-moreau))
 - Added [support for AmmoJS](https://doc.babylonjs.com/how_to/using_the_physics_engine) as a physics plugin (Composite objects, motors, joints) ([TrevorDev](https://github.com/TrevorDev))
-  - Added support for soft bodies in Ammo physics plugin. [Doc](https://doc.babylonjs.com/how_to/soft_bodies) ([JohnK](https://github.com/
-  - Added support for [Convex Hull Impostor][https://github.com/kripken/ammo.js/blob/master/bullet/src/BulletCollision/CollisionShapes/btConvexHullShape.h] using Ammo.js plugin ([MackeyK24](https://github.com/mackeyk24))BabylonJSGuide))
+  - Added support for soft bodies in Ammo physics plugin. [Doc](https://doc.babylonjs.com/how_to/soft_bodies) ([JohnK](https://github.com/BabylonJSGuide))
+  - Added support for [Convex Hull Impostor][https://github.com/kripken/ammo.js/blob/master/bullet/src/BulletCollision/CollisionShapes/btConvexHullShape.h] using Ammo.js plugin ([MackeyK24](https://github.com/mackeyk24))
 - Added support for [WebXR](https://doc.babylonjs.com/how_to/webxr) ([TrevorDev](https://github.com/TrevorDev))
   - Add customAnimationFrameRequester to allow sessions to hook into engine's render loop ([TrevorDev](https://github.com/TrevorDev))
   - camera customDefaultRenderTarget to allow cameras to render to a custom render target (eg. xr framebuffer) instead of the canvas ([TrevorDev](https://github.com/TrevorDev))

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

+ 27 - 7
src/Physics/Plugins/ammoJSPlugin.ts

@@ -223,6 +223,7 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
      * @param impostor imposter to match
      */
     public afterSoftStep(impostor: PhysicsImpostor): void {
+        var normalDirection = (impostor.type === PhysicsImpostor.ClothImpostor) ? 1 : -1;
         var object = impostor.object;
         var vertexPositions = object.getVerticesData(VertexBuffer.PositionKind);
         if (!vertexPositions) {
@@ -245,11 +246,11 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
             nodePositions = node.get_m_x();
             x = nodePositions.x();
             y = nodePositions.y();
-            z = -nodePositions.z();
+            z = nodePositions.z() * normalDirection;
             var nodeNormals = node.get_m_n();
             nx = nodeNormals.x();
             ny = nodeNormals.y();
-            nz = -nodeNormals.z();
+            nz = nodeNormals.z() * normalDirection;
 
             vertexPositions[3 * n] = x;
             vertexPositions[3 * n + 1] = y;
@@ -655,12 +656,12 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
             else {
                 var len = vertexPositions.length;
                 var segments = Math.sqrt(len / 3);
-                impostor.segments = segments - 1;
+                impostor.segments = segments;
                 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(),
@@ -673,6 +674,7 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
                     impostor.getParam("fixedPoints"),
                     true
                 );
+                clothBody.get_m_cfg().set_collisions(0x11);
                 return clothBody;
             }
         }
@@ -1156,6 +1158,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 influence 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 - 1) * width);
+        var nbUp = Math.round((segs - 1) * height);
+        var nbDown = segs - 1 - 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 width ratio across width from 0 to 1
+     * @param height ratio up height from 0 to 1
+     * @param influence 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
+     * @returns impostor 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
      */