Advertisement
Guest User

Physics

a guest
Jun 17th, 2019
411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  
  3.     Usage :
  4.     -----------------------------------------
  5.     ↓ Init ↓
  6.     Parameters :
  7.      - scene => Object : Scene de ThreeJS
  8.      - {} => Object : Parametres d'intialisation
  9.         - helper => Boolean : Wireframe de la physique de chaque objects
  10.     Exemple :
  11.     const physics = new Physics(scene, {
  12.         helper: true
  13.     })
  14.     -----------------------------------------
  15.     ↓ Add ↓
  16.     Parameters:
  17.      - 'floor' => String : Object à ajouter (box, sphere, stone, character, floor, coral)
  18.      - {} => Object : Parametres d'intialisation
  19.         - size => Object => Int : Taille de l'object en xyz
  20.         - radius => Int : Radius de l'object
  21.         - position => Object => Int: Position de l'object en xyz
  22.         - rotation => Int : Rotation de l'object en PI
  23.         - mass => Int : masse de l'object (0 = pas de gravité, n>0 = gravité )
  24.         - materials => Object : Texture de l 'object
  25.             - state => Int : Etat de l 'object (1, 2, 3) // Pas obligatoire
  26.             - texture => String : Type de texture de l 'object (default, sand, bush, tree, stone, mountain, stalagmite, bubble, lava)
  27.     Exemple:
  28.      physics.add('floor', {
  29.         // Global variables
  30.         size: {
  31.             x: 1,
  32.             y: 1,
  33.             z: 1
  34.         },
  35.         radius: 1,
  36.         position: {
  37.             x: 1,
  38.             y: 1,
  39.             z: 1
  40.         },
  41.         rotation: -Math.PI / 2,
  42.         // Physics variables
  43.         mass: 5,
  44.         // Graphics variables
  45.         materials: {
  46.             state: 1,
  47.             texture: 'default'
  48.         }
  49.     })
  50.     -----------------------------------------
  51.     ↓ Update ↓
  52.     Parameters:
  53.      - time => Float : Temps depuis le début du lancement
  54.     Exemple:
  55.      physics.update(time)
  56. */
  57.  
  58. import CANNON from "../../../core/cannon"
  59. import CANNONHELPERS from "../../../core/cannonHelpers"
  60. import 'three/examples/js/loaders/GLTFLoader';
  61. import { resolve } from "q";
  62. import { cpus } from "os";
  63. import { brotliCompressSync } from "zlib";
  64. import Materials from './Materials';
  65. import SimplexNoise from 'simplex-noise';
  66. import Character from '../player/Character';
  67.  
  68. export default class Physics {
  69.     constructor(scene, opts) {
  70.         // Initialize variables
  71.         this.world;
  72.         this.gravity = opts.gravity ? opts.gravity : -10;
  73.         this.helper = opts.helper;
  74.         this.scene = scene;
  75.         // Update variables
  76.         this.fixedTimeStep = 1 / 60;
  77.         this.maxSubSteps = 3;
  78.         this.lastTime;
  79.         // Globals variables
  80.         this.character = {};
  81.         this.floors = {
  82.             meshes: [],
  83.             bodies: []
  84.         };
  85.         this.objects = {
  86.             meshes: [],
  87.             bodies: []
  88.         };
  89.         this.sources = {
  90.             coral: '/assets/medias/meshes/coral.gltf'
  91.         };
  92.         this.meshes = {};
  93.         this.elements = [];
  94.         this.loaded = false;
  95.         // Initiliaze physics
  96.         this.initialize();
  97.         // Load meshes
  98.         this.loader();
  99.     }
  100. // ---
  101.     initialize() {
  102.         this.world = new CANNON.World();
  103.         this.world.gravity.set(0, this.gravity, 0);
  104.         this.world.broadphase = new CANNON.NaiveBroadphase();
  105.         this.helper && (this.helper = new THREE.CannonDebugRenderer(this.scene, this.world));
  106.     }
  107.     update(time) {
  108.     // Time
  109.         if (time && this.lastTime) {
  110.             let dt = time - this.lastTime;
  111.             this.world.step(this.fixedTimeStep, dt / 1000, this.maxSubSteps);
  112.         }
  113.         this.lastTime = time;
  114.     // Charater
  115.         if (this.character.mesh) {
  116.             this.character.mesh.position.copy(this.character.body.position);
  117.             this.character.mesh.quaternion.copy(this.character.body.quaternion);
  118.         }
  119.         if (this.character.body) {
  120.             // this.character.body.character.update()
  121.         }
  122.     // Floor
  123.         if (this.floors.meshes) {
  124.             for (let i = 0; i !== this.floors.meshes.length; i++) {
  125.                 this.floors.meshes[i].position.copy(this.floors.bodies[i].position);
  126.                 this.floors.meshes[i].quaternion.copy(this.floors.bodies[i].quaternion);
  127.                 this.floors.meshes[i].material.texture.update(time);
  128.             }
  129.         }
  130.     // Objects
  131.         if (this.objects.meshes) {
  132.             for (let i = 0; i !== this.objects.meshes.length; i++) {
  133.                 this.objects.meshes[i].position.copy(this.objects.bodies[i].position);
  134.                 this.objects.meshes[i].quaternion.copy(this.objects.bodies[i].quaternion);
  135.                 this.objects.meshes[i].material.texture.update(time);
  136.             }
  137.         }
  138.     // Helper
  139.         this.helper && (this.helper.update());
  140.     }
  141. // ---
  142.     add(object, options) {
  143.         this.elements.push([object, options]);
  144.         (this.loaded) && this.draw(object, options);
  145.     }
  146. // ---
  147.     async loader() {
  148.         Object.assign(this.meshes, this.sources);
  149.         this.meshes.coral = await this.load(this.sources.coral);
  150.         this.mount();
  151.         this.loaded = true;
  152.     }
  153.     load(url) {
  154.         return new Promise(resolve => {
  155.             const loader = new THREE.GLTFLoader();
  156.             loader.load(
  157.                 window.DIR + url,
  158.                 obj => {
  159.                     resolve(obj.scene.children[0]);
  160.                 },
  161.                 xhr => {},
  162.                 err => {}
  163.             );
  164.         })
  165.     }
  166. // ---
  167.     mount() {
  168.         for (let i = 0; i < this.elements.length; i++) {
  169.             const element = this.elements[i];
  170.             this.draw(element[0], element[1]);
  171.         }
  172.     }
  173. // ---
  174.     draw(object, options) {
  175.         // Update
  176.         const opts = Object.assign({
  177.             // Global variables
  178.             groundID: 4,
  179.             size: {x:1, y:1, z:1},
  180.             radius: 1,
  181.             position: {x:0, y:0, z:0},
  182.             rotation: -Math.PI / 2,
  183.             is: true,
  184.             // Physics variables
  185.             shape: null,
  186.             body: null,
  187.             mass: 5,
  188.             // Graphics variables
  189.             geometry: null,
  190.             materials: {
  191.                 state: 1,
  192.                 texture: 'default'
  193.             },
  194.             material: null,
  195.             mesh: null
  196.         }, options);
  197.         opts.name = object
  198.         // Route
  199.         switch (object) {
  200.             case 'box':
  201.                 this.drawBox(opts)
  202.                 break;
  203.             case 'sphere':
  204.                 opts.detail = 5;
  205.                 this.drawIcosahedron(opts)
  206.                 break;
  207.             case 'stone':
  208.                 opts.detail = 1;
  209.                 this.drawIcosahedron(opts)
  210.                 break;
  211.             case 'chunk':
  212.                 this.drawPlane(opts)
  213.                 break;
  214.             case 'character':
  215.                 opts.detail = 5;
  216.                 opts.character = true;
  217.                 this.drawIcosahedron(opts)
  218.                 break;
  219.             case 'coral':
  220.                 this.drawComplex(opts)
  221.                 break;
  222.             default:
  223.                 this.drawBox(opts)
  224.                 break;
  225.         }
  226.     }
  227.     drawBox(options) {
  228.     // Initialize
  229.         let size = options.size;
  230.         let position = options.position;
  231.         let rotation = options.rotation;
  232.         let shape = options.shape;
  233.         let body = options.body;
  234.         let mass = options.mass;
  235.         let geometry = options.geometry;
  236.         let materials = options.materials;
  237.         let material = options.material;
  238.         let mesh = options.mesh;
  239.         let name = options.name;
  240.         let is = options.is;
  241.         let groundID = options.groundID;
  242.     // Update
  243.         size.x = size.x / 2;
  244.         size.y = size.y / 2;
  245.         size.z = size.z / 2;
  246.     // Physics
  247.         shape = new CANNON.Box(
  248.             new CANNON.Vec3(size.x, size.y, size.z)
  249.         );
  250.         body = new CANNON.Body({
  251.             mass: mass
  252.         });
  253.         body.addShape(shape);
  254.         body.position.set(position.x, position.y, position.z);
  255.         body.quaternion.setFromAxisAngle(
  256.             new CANNON.Vec3(0, 1, 0),
  257.             rotation
  258.         );
  259.     // Update
  260.         size.x = (materials.texture == 'lava') ? size.x : size.x * 2;
  261.         size.y = (materials.texture == 'lava') ? size.y : size.y * 2;
  262.         size.z = (materials.texture == 'lava') ? size.z : size.z * 2;
  263.     // Graphics
  264.         geometry = new THREE.BoxBufferGeometry(size.x, size.y, size.z, 32, 32, 32);
  265.         materials = new Materials(materials);
  266.         material = materials.material;
  267.         material.texture = materials;
  268.         mesh = new THREE.Mesh(geometry, material);
  269.         mesh.position.set(position.x, position.y, position.z);
  270.         mesh.quaternion.setFromAxisAngle(
  271.             new THREE.Vector3(0, 1, 0),
  272.             rotation
  273.         );
  274.         mesh.name = name;
  275.         mesh.is = is;
  276.     // Global
  277.         this.world.addBody(body);
  278.         this.objects.bodies.push(body);
  279.         // this.scene.add(mesh);
  280.         this.objects.meshes.push(mesh);
  281.         window.grounds[groundID].objects.push(mesh);
  282.     }
  283.     drawIcosahedron(options) {
  284.         // Initialize
  285.         let radius = options.radius;
  286.         let detail = options.detail;
  287.         let position = options.position;
  288.         let rotation = options.rotation;
  289.         let shape = options.shape;
  290.         let body = options.body;
  291.         let mass = options.mass;
  292.         let geometry = options.geometry;
  293.         let materials = options.materials;
  294.         let material = options.material;
  295.         let mesh = options.mesh;
  296.         let character = options.character;
  297.         let name = options.name;
  298.         let is = options.is;
  299.         let groundID = options.groundID;
  300.         // Physics
  301.         shape = new CANNON.Sphere(radius);
  302.         body = new CANNON.Body({
  303.             mass: mass
  304.         });
  305.         body.addShape(shape);
  306.         body.position.set(position.x, position.y, position.z);
  307.         body.quaternion.setFromAxisAngle(
  308.             new CANNON.Vec3(0, 1, 0),
  309.             rotation
  310.         );
  311.         // Graphics
  312.         geometry = new THREE.IcosahedronBufferGeometry(radius, detail);
  313.         materials = new Materials(materials);
  314.         material = materials.material;
  315.         material.texture = materials;
  316.         mesh = new THREE.Mesh(geometry, material);
  317.         mesh.position.set(position.x, position.y, position.z);
  318.         mesh.quaternion.setFromAxisAngle(
  319.             new THREE.Vector3(0, 1, 0),
  320.             rotation
  321.         );
  322.         mesh.name = name;
  323.         mesh.is = is;
  324.         // Global
  325.         this.world.addBody(body);
  326.         console.log(character)
  327.         if (character) {
  328.             this.character.body = body;
  329.             this.character.body.character = new Character()
  330.             console.log(this.character.body.character)
  331.         } else {
  332.             this.objects.bodies.push(body);
  333.         }
  334.         // (character) || this.scene.add(mesh);
  335.         (character) || this.objects.meshes.push(mesh);
  336.         window.grounds[groundID].objects.push(mesh);
  337.     }
  338.     drawPlane(options) {
  339.     // Initialize
  340.         let size = options.size;
  341.         let position = options.position;
  342.         let rotation = options.rotation;
  343.         let matrix = [];
  344.         let shape = options.shape;
  345.         let body = options.body;
  346.         let mass = options.mass;
  347.         let geometry = options.geometry;
  348.         let materials = options.materials;
  349.         let material = options.material;
  350.         let mesh = options.mesh;
  351.         let groundID = options.groundID;
  352.     // Update
  353.         size.x = (materials.texture == 'lava') ? size.x / 4 : size.x / 2;
  354.         size.y = (materials.texture == 'lava') ? size.y / 4 : size.y / 2;
  355.         size.z = (materials.texture == 'lava') ? size.z / 4 : size.z / 2;
  356.     // Physics
  357.         for (let i = 0; i < size.x; i++) {
  358.             matrix.push([]);
  359.             for (let j = 0; j < size.y; j++) {
  360.                 let height = Math.sin(i / size.x * Math.PI * 2) * Math.cos(j / size.y * Math.PI * 2);
  361.                 height *= (materials.texture == 'lava') ? 0 : 0.75;
  362.                 matrix[i].push(height);
  363.             }
  364.         }
  365.         shape = new CANNON.Heightfield(matrix, {
  366.             elementSize: (materials.texture == 'lava') ? 2.25 : 5
  367.         });
  368.         body = new CANNON.Body({
  369.             mass: mass
  370.         });
  371.         body.addShape(shape);
  372.         body.position.set(position.x, position.y, position.z);
  373.         body.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), rotation);
  374.     // Update
  375.         size.x = size.x;
  376.         size.y = size.y;
  377.         size.z = size.z;
  378.     // Graphics
  379.         geometry = new THREE.Geometry();
  380.         let v0 = new CANNON.Vec3();
  381.         let v1 = new CANNON.Vec3();
  382.         let v2 = new CANNON.Vec3();
  383.         for (let xi = 0; xi < shape.data.length - 1; xi++) {
  384.             for (let yi = 0; yi < shape.data[xi].length - 1; yi++) {
  385.                 for (let k = 0; k < 2; k++) {
  386.                     shape.getConvexTrianglePillar(xi, yi, k === 0);
  387.                     v0.copy(shape.pillarConvex.vertices[0]);
  388.                     v1.copy(shape.pillarConvex.vertices[1]);
  389.                     v2.copy(shape.pillarConvex.vertices[2]);
  390.                     v0.vadd(shape.pillarOffset, v0);
  391.                     v1.vadd(shape.pillarOffset, v1);
  392.                     v2.vadd(shape.pillarOffset, v2);
  393.                     geometry.vertices.push(
  394.                         new THREE.Vector3(v0.x, v0.y, v0.z),
  395.                         new THREE.Vector3(v1.x, v1.y, v1.z),
  396.                         new THREE.Vector3(v2.x, v2.y, v2.z)
  397.                     );
  398.                     let i = geometry.vertices.length - 3;
  399.                     geometry.faces.push(new THREE.Face3(i, i + 1, i + 2));
  400.                 }
  401.             }
  402.         }
  403.         geometry.computeBoundingSphere();
  404.         geometry.computeFaceNormals();
  405.         materials = new Materials(materials);
  406.         material = materials.material;
  407.         material.texture = materials;
  408.         mesh = new THREE.Mesh(geometry, material);
  409.         mesh.position.set(position.x, position.y, position.z);
  410.         mesh.quaternion.setFromAxisAngle(
  411.             new THREE.Vector3(0, 1, 0),
  412.             rotation
  413.         );
  414.     // Global
  415.         this.world.addBody(body);
  416.         this.floors.bodies.push(body);
  417.         // this.scene.add(mesh);
  418.         this.floors.meshes.push(mesh);
  419.         window.grounds[groundID].elmt = mesh;
  420.         window.grounds[groundID].elmt.body = body;
  421.     }
  422.     drawComplex(options) { // TODO : resize body + center mesh on the body
  423.     // Initialize
  424.         let size = options.size;
  425.         let position = options.position;
  426.         let rotation = options.rotation;
  427.         let shape = options.shape;
  428.         let body = options.body;
  429.         let mass = options.mass;
  430.         let geometry = options.geometry;
  431.         let materials = options.materials;
  432.         let material = options.material;
  433.         let mesh = options.mesh;
  434.         let name = options.name;
  435.         let is = options.is;
  436.         let groundID = options.groundID;
  437.         for (let i = 0; i < this.meshes.coral.children.length; i++) {
  438.         // Physics
  439.             mesh = this.meshes.coral.children[i];
  440.             shape = new CANNON.Box(
  441.                 new CANNON.Vec3(size.x, size.y, size.z)
  442.             );
  443.             body = new CANNON.Body({
  444.                 mass: mass
  445.             });
  446.             body.addShape(shape);
  447.             body.position.set(position.x * i, position.y * i, position.z);
  448.             body.quaternion.setFromAxisAngle(
  449.                 new CANNON.Vec3(0, 1, 0),
  450.                 rotation
  451.             );
  452.         // Graphics
  453.             geometry = mesh.geometry;
  454.             materials = new Materials(options.materials);
  455.             material = materials.material;
  456.             material.texture = materials;
  457.             mesh = new THREE.Mesh(geometry, material);
  458.             mesh.position.set(position.x, position.y, position.z);
  459.             mesh.quaternion.setFromAxisAngle(
  460.                 new THREE.Vector3(0, 1, 0),
  461.                 rotation
  462.             );
  463.             mesh.scale.set(options.size.x, options.size.y, options.size.z);
  464.             mesh.name = name;
  465.             mesh.is = is;
  466.         // Global
  467.             this.world.addBody(body);
  468.             this.objects.bodies.push(body);
  469.             // this.scene.add(mesh);
  470.             this.objects.meshes.push(mesh);
  471.             window.grounds[groundID].objects.push(mesh);
  472.         }
  473.     }
  474. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement