BabylonJS - Mesh

In questo capitolo impareremo a creare forme diverse usando il generatore di mesh. Abbiamo già imparato a creare forme in uno dei nostri capitoli precedenti.

La differenza è che con meshbuilder ti dà la flessibilità di aggiungere colori e immagini alle forme.

CreateBox utilizzando MeshBuilder

Vediamo ora come creare box utilizzando MeshBuilder.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 0, 1);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0, 1, 0);
            
            var texture = new BABYLON.Texture("images/cube.png", scene);
            mat.diffuseTexture = texture;

            var hSpriteNb =  3;  // 3 sprites per raw
            var vSpriteNb =  2;  // 2 sprite raws

            var faceUV = new Array(6);
            for (var i = 0; i < 6; i++) {
               faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
            }

            var options = {
               width: 1.5,
               height: 1.5,
               depth: 1.5,
               faceUV: faceUV
            };

            var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
            box.material = mat;

            scene.registerBeforeRender(function() { 
               pl.position = camera.position;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

La riga di codice sopra genera il seguente output:

Per l'esempio sopra, abbiamo usato un'immagine sprite come mostrato di seguito. Ha 3 colonne orizzontali e 2 file verticali.

In questa demo, abbiamo utilizzato un'immagine chiamata cube.png. Le immagini sono memorizzate in immagini / cartella localmente e vengono anche incollate di seguito per riferimento. Nota che cube.png è un'immagine sprite, un'immagine sprite è una raccolta di immagini. Volevamo mostrare l'immagine su un cubo, quindi volevamo tutti i lati del cubo insieme. Puoi anche scaricare immagini di sprite simili a tua scelta e utilizzarle nel link demo.

Il generatore di createBox ti offre opzioni per le dimensioni.

Per esempio,

var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);

Demo

var hSpriteNb =  3;  // 3 sprites per raw ie colums horizontally as shown in the image

var vSpriteNb =  2;  // 2 sprite raws as shown in the image above.

var faceUV = new Array(6); // the cube has 6 sides so creating array for same.
for (var i = 0; i < 6; i++) {
   faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
}

var options = {
   width: 1.5,
   height: 1.5,
   depth: 1.5,
   faceUV: faceUV
};

Questo si chiama applicare le texture al meshbuilder usando il metodo createBox. Abbiamo usato l'immagine cube.png che ha orizzontalmente 3 colonne e verticalmente 2 file. Il cubo o scatola ha 6 lati.

Per applicare le trame utilizziamo il parametro delle opzioni, ad esempio

Var box = BABYLON.MeshBuilder.CreateBox ('box', options, scene);

Abbiamo definito un array chiamato faceUV con dimensione 6 che sono i lati del cubo. Questo array avrà sempre elementi Vector4. Ogni Vector4 (x, y, z, w) sarà definito come segue:

  • x = Ubottom
  • y = Vbottom
  • z = Utop
  • w = Vtop

I vettori sono nell'intervallo [0, 1]. Ubottom e Vbottom sono le coordinate 2D del punto in basso a sinistra di dove inizia il ritaglio della trama. Utop, Vtop sono i punti in alto a destra dove finisce il ritaglio della texture.

var hSpriteNb =  3;  // 3 sprites per raw
var vSpriteNb =  2;  // 2 sprite raws

var faceUV = new Array(6);
for (var i = 0; i < 6; i++) {
   faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
}

Supponiamo che la texture di default, cioè l'immagine data sia applicata a tutte le facce della scatola. Se desideri modificare solo 1 faccia o 1 lato della scatola, puoi assegnare direttamente i valori come mostrato di seguito -

var hSpriteNb =  3;  // 3 sprites per raw
var vSpriteNb =  2;  // 2 sprite raws

var faceUV = new Array(6);
faceUV[4] = new BABYLON.Vector4(0, 0, 1/hSpriteNb, 1/vSpriteNb);

Esempio

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 0, 1);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.8, 0.8, 0.8);
            
            var texture = new BABYLON.Texture("images/3d.png", scene);
            mat.diffuseTexture = texture;

            var hSpriteNb =  3;  // 3 sprites per raw
            var vSpriteNb =  2;  // 2 sprite raws

            var faceUV = new Array(6);
            faceUV[4] = new BABYLON.Vector4(0, 0, 1/hSpriteNb, 1/vSpriteNb);

            var options = {
               width:3,
               height:3,
               depth: 3,
               faceUV:faceUV
            };

            var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
            box.material = mat;

            scene.registerBeforeRender(function() { 
               pl.position = camera.position;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

La riga di codice sopra genera il seguente output:

In questa demo abbiamo usato un'immagine chiamata 3d.png. Le immagini sono memorizzate in immagini / cartella localmente e vengono anche incollate di seguito per riferimento. Nota che 3d.png è un'immagine sprite; un'immagine sprite è una raccolta di immagini. Volevamo mostrare l'immagine su un cubo con tutti i lati del cubo insieme. Puoi anche scaricare immagini di sprite simili a tua scelta e utilizzarle nel link demo.

Texture utilizzata per la scatola - images/3d.png

MeshCylinder

In questa sezione vedremo come creare MeshCylinder.

Per creare MeshCylinder, è necessario utilizzare la classe BABYLON.MeshBuilder.CreateCylinder.

I parametri per la classe sono i seguenti:

var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
   height: 3,
   diameter: 35,
   tessellation: 52
}, scene);

La differenza tra CreateCylinder usando mesh e meshbuilder è che puoi usare le opzioni in meshbuilder. In questo momento stiamo usando altezza, diametro e tassellatura come opzioni da passare al cilindro. Stiamo usando materiale standard con wireframe come materiale per questa rete. Controlla l'output nel browser e guarda il cilindro. Puoi usare una struttura simile nel tuo gioco come una ruota che gira nella scena.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>Babylon.js demo - Mesh Builder</title>
      <script src = "babylon.js"></script>
      <style>
         html,body,canvas { margin: 0; padding: 0; width: 100%; height: 100%; font-size: 0; }
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0.8, 0.8, 0.8);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 6, 1.3, 40, new BABYLON.Vector3(0, -3, 0), scene);
            
            var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);

            var mat = new BABYLON.StandardMaterial("mat", scene);
            mat.diffuseColor = new BABYLON.Color3(0.1, .5, 0);
            mat.specularColor = new BABYLON.Color3(0, 0, 0);
            mat.wireframe = true;

            var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
               height: 3,
               diameter: 35,
               tessellation: 52
            }, scene);

            meshcylinder.material = mat;
            meshcylinder.position = new BABYLON.Vector3(0, 0, 0);

            scene.activeCamera.attachControl(canvas);
            return scene;
         };
         
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

La riga di codice sopra genera il seguente output:

Un certo numero di forme create con il generatore di mesh verranno ora utilizzate insieme in una demo. Le forme trattate nel collegamento demo di seguito sono elencate nelle sezioni successive.

  • Ground

  • Cone

  • Plane

  • Disc

  • Torus

  • Polyhedron

  • IcoSphere

BabylonJS - Intersezione e punto della mesh

L'intersezione mesh nei giochi è importante perché sai cosa è necessario fare quando 2 oggetti si intersecano in un gioco. Lo stesso concetto è spiegato nella demo di seguito sull'evento che deve essere catturato quando le mesh si intersecano.

Nella demo fornita di seguito, abbiamo coperto i seguenti due concetti:

  • Maglia di intersezione
  • Punto di intersezione
<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);
            
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var matcone = new BABYLON.StandardMaterial("mat1", scene);
            matcone.alpha = 1.0;
            matcone.diffuseColor = new BABYLON.Color3(0, 0, 0);
            matcone.wireframe = true;

            var cone = BABYLON.MeshBuilder.CreateCylinder("cone", {height : 10, diameterTop: 10,diameterBottom:10, tessellation: 5}, scene);
            cone.position= new BABYLON.Vector3(12,1,0);
            cone.material = matcone;	

            var balloon1 = BABYLON.Mesh.CreateSphere("balloon1",5, 1.0, scene);
            var balloon2 = BABYLON.Mesh.CreateSphere("balloon2", 5, 1.0, scene);
            var balloon3 = BABYLON.Mesh.CreateSphere("balloon3", 5, 1.0, scene);
            
            balloon1.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon2.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon3.material = new BABYLON.StandardMaterial("matBallon", scene);

            balloon1.position = new BABYLON.Vector3(4, 2, 0);
            balloon2.position = new BABYLON.Vector3(5, 1, 0);
            balloon3.position = new BABYLON.Vector3(7, 0, 0);

            var pointToIntersect = new BABYLON.Vector3(10, 0, 0);
            var a = 0.01;
            
            scene.registerBeforeRender(function () {
               if (balloon1.intersectsMesh(cone, false)) {
                  balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } else {
                  balloon1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon2.intersectsMesh(cone, false)) {
                  balloon2.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } else {
                  balloon2.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon3.intersectsMesh(cone, false)) {
                  balloon3.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } else {
                  balloon3.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon3.intersectsPoint(pointToIntersect)) {
                  balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
               }

               a += 0.01;
               balloon1.position.x += Math.cos(a) / 10;
               balloon2.position.x += Math.cos(a) / 10;
               balloon3.position.x += Math.cos(a) / 10;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

Il codice precedente genera il seguente output:

Spiegazione

Con il codice sopra, abbiamo creato un cilindro con wireframe come true. Abbiamo creato 3 sfere. Il colore originale della sfera è il verde.

Nel scene.registerBeforeRender funzione, cambieremo il colore della sfera in base all'intersezione con la mesh che qui è il cilindro.

Considera il codice seguente in registerBeforeRender -

if (balloon1.intersectsMesh(cone, false)) {
   balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
} else {
   balloon1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
}

intersectsMesh restituisce vero o falso se si interseca con la mesh data nel parametro passato ad essa.

Per esempio,

balloon1.intersectsMesh(cone, false); //cone refers to the cylinder mesh here.

Il colore della sfera diventa rosso e si interseca con il cilindro; in caso contrario, è verde.

Il codice seguente viene utilizzato per l'intersezione del punto:

var pointToIntersect = new BABYLON.Vector3(10, 0, 0);
if (balloon3.intersectsPoint(pointToIntersect)) {
   balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
}

Qui, pointtoIntersectvariabile è il vettore di posizione che è 10 sull'asse x. Se la sfera attraversa il punto di intersezione, il colore della sfera diventa nero.

BabylonJS - MeshPicking Collision

La selezione della collisione ti dà effettivamente le coordinate e puoi posizionare la tua mesh in quel punto. L'oggetto viene selezionato dal mouse e puoi semplicemente posizionarlo dove fai clic con il mouse. Considera che devi posizionare una mesh (oggetto) in un punto in cui l'utente fa clic con il mouse; quindi, con l'aiuto del picking collision ti aiuta con le coordinate nella posizione del luogo cliccato.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);

            // setup environment
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 10, 20), scene);
            var freeCamera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, -30), scene);

            var balloon1 = BABYLON.Mesh.CreateSphere("balloon1",5, 1.0, scene);
            var balloon2 = BABYLON.Mesh.CreateSphere("balloon2", 5, 1.0, scene);
            balloon1.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon2.material = new BABYLON.StandardMaterial("matBallon", scene);

            balloon1.position = new BABYLON.Vector3(0, 0, -0.1);
            balloon2.position = new BABYLON.Vector3(0, 0, -0.1);
            balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
            balloon2.material.emissiveColor = new BABYLON.Color3(0, 0, 1);

            //Wall
            var wall = BABYLON.Mesh.CreatePlane("wall", 30.0, scene);
            wall.material = new BABYLON.StandardMaterial("wallMat", scene);
            wall.material.emissiveColor = new BABYLON.Color3(0.5, 1, 0.5);

            //When pointer down event is raised

            scene.onPointerDown = function (evt, pickResult) {
               // if the click hits the ground object, we change the impact position
               if (pickResult.hit) {
                  var dateValue = new Date();
                  var secondNumber = dateValue.getSeconds();
                  if (secondNumber % 2 == 0) {
                  balloon1.position.x = pickResult.pickedPoint.x;
                  balloon1.position.y = pickResult.pickedPoint.y;
                  } else {
                     balloon2.position.x = pickResult.pickedPoint.x;
                     balloon2.position.y = pickResult.pickedPoint.y;
                  }
               }
            };
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

Spiegazione

Nell'esempio sopra, abbiamo usato un piano e 2 sfere. Per generare questo output, utilizzare il codice seguente:

scene.onPointerDown = function (evt, pickResult) {
   // if the click hits the ground object, we change the impact position
   if (pickResult.hit) {
      var dateValue = new Date();
      var secondNumber = dateValue.getSeconds();
      if (secondNumber % 2 == 0) {
      balloon1.position.x = pickResult.pickedPoint.x;
      balloon1.position.y = pickResult.pickedPoint.y;
      } else {
         balloon2.position.x = pickResult.pickedPoint.x;
         balloon2.position.y = pickResult.pickedPoint.y;
      }
   }
};

L'evento scene.onPointerDown ti dà le coordinate -x, yez che nel nostro esempio è pickResult.

Se si fa clic sulla mesh del terreno, pickResult.hit è vero. Consideriamo i secondi pari / dispari e cambiamo la posizione della sfera per selezionare le coordinate del risultato ze y come mostrato sopra. Una volta modificata la posizione, la sfera viene posizionata dove fai clic e posiziona il mouse. Puoi provare la demo sopra per lo stesso.

BabylonJS - Raycasts

I raycast sono come i raggi del sole e vengono utilizzati per controllare la collisione e l'intersezione nella scena.

Sintassi

var ray = new BABYLON.Ray(origin, direction, length);

Parametri

Considera i seguenti parametri per i raycast:

  • Origin - Luogo in cui inizierà il raggio.

  • Direction - La direzione del raggio viene calcolata come segue:

var forward = new BABYLON.Vector3(0,0,1);		
forward = vecToLocal(forward, box);
var direction = forward.subtract(origin);

Quindi, per ottenere la direzione, la sottraiamo dall'origine, la posizione del riquadro -

  • Length - Lunghezza del raggio.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, new BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var ground = BABYLON.Mesh.CreateGround("ground", 500, 500, 10, scene);

            var box = BABYLON.Mesh.CreateBox("box", 4.0, scene);
            box.position.y = 2;
            box.scaling.z = 2;
           
            var matBox = new BABYLON.StandardMaterial("matBox", scene);
            matBox.diffuseColor = new BABYLON.Color3(0.8, 0.1, 0.5);
            box.material = matBox;
            box.isPickable = false; 

            var box2 = BABYLON.Mesh.CreateBox("box2", 8.0, scene);
            box2.position = new BABYLON.Vector3(-20, 4, 0); 
            
            var matBox2 = new BABYLON.StandardMaterial("matBox2", scene);
            matBox2.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box2.material = matBox2;

            var box3 = BABYLON.Mesh.CreateBox("box3", 8.0, scene);
            box3.position = new BABYLON.Vector3(20, 4, 0); 
            
            var matBox3 = new BABYLON.StandardMaterial("matBox3", scene);
            matBox3.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box3.material = matBox3;

            var box4 = BABYLON.Mesh.CreateBox("box4", 8.0, scene);
            box4.position = new BABYLON.Vector3(0, 0, 20); 
            
            var matBox4 = new BABYLON.StandardMaterial("matBox4", scene);
            matBox4.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box4.material = matBox4;

            var box5 = BABYLON.Mesh.CreateBox("box5", 8.0, scene);
            box5.position = new BABYLON.Vector3(0, 0, -20); 
            
            var matBox5 = new BABYLON.StandardMaterial("matBox5", scene);
            matBox5.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box5.material = matBox5;

            function mousemovef() {
               var pickResult = scene.pick(scene.pointerX, scene.pointerY);

               if (pickResult.hit) {
                  var diffX = pickResult.pickedPoint.x - box.position.x;
                  var diffY = pickResult.pickedPoint.z - box.position.z;
                  box.rotation.y = Math.atan2(diffX,diffY);			
               }	
            }

            scene.onPointerMove = function () {
               mousemovef();
            };

            function vecToLocal(vector, mesh) {
               var m = mesh.getWorldMatrix();
               var v = BABYLON.Vector3.TransformCoordinates(vector, m);
               return v;		
            }   

            scene.registerBeforeRender(function () {
               var origin = box.position;

               var forward = new BABYLON.Vector3(0,0,1);		
               forward = vecToLocal(forward, box);

               var direction = forward.subtract(origin);
               direction = BABYLON.Vector3.Normalize(direction);

               var length = 100;

               var ray = new BABYLON.Ray(origin, direction, length);
               // ray.show(scene, new BABYLON.Color3(1, 1, 0.1));

               var hit = scene.pickWithRay(ray);

               if (hit.pickedMesh) {
                  hit.pickedMesh.scaling.y  += 0.01;
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

La riga di codice sopra genera il seguente output:

Spiegazione

C'è una scatola principale al centro che funge da raycast. Nel momento in cui punta a una qualsiasi delle caselle, la dimensione della casella aumenterà. Questo concetto si rivela utile durante i giochi per sapere quale altro oggetto viene in contatto e può essere intrapresa l'azione necessaria.

Aggiunta box.isPickable = false;in modo che il riquadro principale al centro non venga considerato. Se non vuoi che nessun oggetto da includere nei raggi entri in contatto, aggiungibox.isPickable = false; ad esso.

Il codice seguente aggiunge il ridimensionamento della scatola che viene selezionata dal raggio.

scene.registerBeforeRender(function () {
   var origin = box.position;	
   var forward = new BABYLON.Vector3(0,0,1);		
   forward = vecToLocal(forward, box);

   var direction = forward.subtract(origin);
   direction = BABYLON.Vector3.Normalize(direction);

   var length = 100;

   var ray = new BABYLON.Ray(origin, direction, length);

   var hit = scene.pickWithRay(ray);

   if (hit.pickedMesh) {
      hit.pickedMesh.scaling.y  += 0.01;
   }
});

var ray = new BABYLON.Ray(origin, direction, length); crea un raggio e prende la posizione del riquadro principale come origine.

La direzione del raggio viene calcolata come segue:

var forward = new BABYLON.Vector3(0,0,1);		
forward = vecToLocal(forward, box);
var direction = forward.subtract(origin);

Quindi, per ottenere la direzione, la sottraiamo dall'origine, la posizione del riquadro. La funzionevecToLocal è progettato per trasformare una posizione dal punto di vista della mesh moltiplicando un vettore per la matrice mesh.

Otteniamo il punto ferita dal raggio usando var hit = scene.pickWithRay(ray);

Fornisce la posizione in cui il raggio coincide con la mesh.

Il ridimensionamento viene applicato alla mesh che viene selezionata eseguendo la seguente riga di codice:

if (hit.pickedMesh) {
   hit.pickedMesh.scaling.y  += 0.01;
}

Prova l'esempio sopra nel browser per vedere l'output.

Raycast con funzione predicato

Vediamo ora come funziona il raycast con la funzione predicato e la direzione mostrata con rayhelper.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, new BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var ground = BABYLON.Mesh.CreateGround("ground", 500, 500, 10, scene);

            var box = BABYLON.Mesh.CreateBox("box", 4.0, scene);
            box.position.y = 2;
            box.scaling.z = 2;
            var matBox = new BABYLON.StandardMaterial("matBox", scene);
            matBox.diffuseColor = new BABYLON.Color3(0.8, 0.1, 0.5);
            box.material = matBox;
            box.isPickable = false; 

            var box2 = BABYLON.Mesh.CreateBox("box2", 8.0, scene);
            box2.position = new BABYLON.Vector3(-20, 4, 0); 
            var matBox2 = new BABYLON.StandardMaterial("matBox2", scene);
            matBox2.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box2.material = matBox2;

            var box3 = BABYLON.Mesh.CreateBox("box3", 8.0, scene);
            box3.position = new BABYLON.Vector3(20, 4, 0); 
            var matBox3 = new BABYLON.StandardMaterial("matBox3", scene);
            matBox3.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box3.material = matBox3;

            var box4 = BABYLON.Mesh.CreateBox("box4", 8.0, scene);
            box4.position = new BABYLON.Vector3(0, 0, 20); 
            var matBox4 = new BABYLON.StandardMaterial("matBox4", scene);
            matBox4.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box4.material = matBox4;

            var box5 = BABYLON.Mesh.CreateBox("box5", 8.0, scene);
            box5.position = new BABYLON.Vector3(0, 0, -20); 
            var matBox5 = new BABYLON.StandardMaterial("matBox5", scene);
            matBox5.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box5.material = matBox5;

            //ray showing the direction
            var ray = new BABYLON.Ray();
            var rayHelper = new BABYLON.RayHelper(ray);

            var localMeshDirection = new BABYLON.Vector3(0, 0, -1);
            var localMeshOrigin = new BABYLON.Vector3(0, 0, -.4);
            var length = 10;

            rayHelper.attachToMesh(box, localMeshDirection, localMeshOrigin, length);
            rayHelper.show(scene);

            function mousemovef() {
               var pickResult = scene.pick(scene.pointerX, scene.pointerY);

               if (pickResult.hit) {
                  var diffX = pickResult.pickedPoint.x - box.position.x;
                  var diffY = pickResult.pickedPoint.z - box.position.z;
                  box.rotation.y = Math.atan2(diffX,diffY);			
               }	
            }

            scene.onPointerMove = function () {
               mousemovef();
            };

            function vecToLocal(vector, mesh) {
               var m = mesh.getWorldMatrix();
               var v = BABYLON.Vector3.TransformCoordinates(vector, m);
               return v;		
            }   

            scene.registerBeforeRender(function () {
               var origin = box.position;
               function predicate(mesh) {
                  if (mesh == box2 || mesh == box || mesh == box5) {
                     return false;
                  }
                  return true;
               }
               
               var forward = new BABYLON.Vector3(0,0,1);		
               forward = vecToLocal(forward, box);

               var direction = forward.subtract(origin);
               direction = BABYLON.Vector3.Normalize(direction);

               var length = 100;

               var ray = new BABYLON.Ray(origin, direction, length);
               // ray.show(scene, new BABYLON.Color3(1, 1, 0.1));

               var hit = scene.pickWithRay(ray, predicate);
               if (hit.pickedMesh) {
                  hit.pickedMesh.scaling.y  += 0.01;
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

La riga di codice sopra genera il seguente output:

Spiegazione

Raycast con funzione predicato aiuta a scegliere quale mesh vogliamo. Se non vogliamo che venga selezionata una mesh, possiamo ignorare lo stesso.

function predicate(mesh) {
   if (mesh == box2 || mesh == box || mesh == box5) {
      return false;
   }
   return true;
}

La funzione precedente fornisce la mesh selezionata dal raggio. Se la mesh selezionata è box2, box o box5, restituirà false; altrimenti, vero.

Puoi provare l'esempio sopra per lo stesso.

BabylonJS - Mesh Shadows

Le ombre vengono renderizzate in base al modo in cui la luce cade sulla mesh creata. Svolgono un ruolo importante nel rendere l'output realistico nel mondo 3D.

Impariamo ora come creare ombre usando babylonjs.

Sintassi

var shadowGenerator00 = new BABYLON.ShadowGenerator(shadowsize, light);

Parametri

Considera i seguenti parametri relativi alle ombre della mesh:

  • Shadowsize - Dimensione dell'ombra.

  • Light - Luce utilizzata nella scena.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);	
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            // light1
            var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(-1, -2, -1), scene);
            light.position = new BABYLON.Vector3(20, 40, 20);

            var ground01 = BABYLON.Mesh.CreateGround("Spotlight Hard Shadows", 24, 60, 1, scene, false);
            var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
            groundMaterial.diffuseTexture = new BABYLON.Texture("images/gr1.jpg", scene);
            groundMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
            groundMaterial.emissiveColor = new BABYLON.Color3(0.2, 0.2, 0.2);

            ground01.material = groundMaterial;
            ground01.receiveShadows = true;
            ground01.position.x = -5;

            var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
            box.position.x = -5;
            box.position.y = 5;
            var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);
            shadowGenerator00.getShadowMap().renderList.push(box);
            //shadowGenerator00.usePoissonSampling = true;
            //shadowGenerator00.useExponentialShadowMap = true;
            shadowGenerator00.useBlurExponentialShadowMap = true;
            shadowGenerator00.bias = 0.01;
            scene.registerBeforeRender(function() {
               box.rotation.x += 0.01;
               box.rotation.x += 0.01;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Produzione

La riga di codice sopra genera il seguente output:

Spiegazione

Per creare ombre, è necessario creare il generatore di ombre. Considera un esempio mostrato di seguito.

var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);

Per definire la mesh per la quale è richiesta l'ombra, è necessario aggiungere la stessa al generatore sopra.

shadowGenerator00.getShadowMap().renderList.push(box);

Ora, abbiamo creato un terreno e una scatola sopra di esso. Vogliamo che l'ombra della scatola cada a terra. Per fare ciò, dobbiamo assicurarci che il terreno sia contrassegnato per ricevere l'ombra, che viene fatto come segue:

ground01.receiveShadows = true;

Sono disponibili alcuni filtri per le ombre che sono i seguenti:

shadowGenerator.usePoissonSampling = true; - Called Poisson sampling 
shadowGenerator.useExponentialShadowMap = true; - Exponential Shadow Map
shadowGenerator.useBlurExponentialShadowMap= true;  - Blur Exponential Shadow Map

Nella nostra demo, abbiamo usato shadowGenerator00.useBlurExponentialShadowMap = true; Puoi provare gli altri e vedere come appare l'output.

Qui abbiamo usato un'immagine chiamata gr1.jpg. Le immagini vengono memorizzate nella cartella immagini / localmente. Puoi scaricare qualsiasi immagine di tua scelta e utilizzarla nel link demo.

BabylonJS - Trame avanzate su mesh

In questa sezione, impareremo le texture avanzate sulle mesh. Le diverse trame sono mostrate di seguito:

  • Struttura del cubo

  • Texture a specchio e urto

  • Texture video

Applichiamo una trama complessa alla trama: specchio, protuberanza, video e rifrazione.

Sr.No. Maglia e descrizione
1 MeshHightlight Layer

Il livello di evidenziazione viene utilizzato per evidenziare la trama nella scena. Puoi dargli colore e il colore viene applicato ai bordi della maglia. Nel caso in cui in un gioco si desideri evidenziare, il livello mesh hightlight può essere utilizzato per lo stesso.

2 Morph a Mesh

Il morphing cambia la forma di un oggetto in un altro con qualche mezzo di transizione. Abbiamo visto il parametro aggiornabile per le forme; altrimenti il ​​parametro è impostato su false. Per il morphing, è impostato su true e la mesh viene aggiornata per cambiare la forma.

3 Azioni su Mesh

Le azioni vengono utilizzate per aggiungere interazione alla mesh. Gli eventi vengono attivati ​​quando si fa clic sulla mesh o quando la mesh si interseca o collide.

4 Mesh AssetsManager

Con la classe assestsmanager, puoi caricare mesh, immagini e file binari nella scena.

5 Importa mesh

Usando Import Mesh impareremo.

6 Obiettivi Mesh Morph

Abbiamo già visto il morphing di linee, nastri, poligoni, ecc. Ora, vedremo il morphing di sfere e box in questa demo. Con i morph target, la forma della sfera è cambiata come si vede nella demo qui sotto.

7 Istanze mesh

Se vuoi disegnare mesh identiche nella tua scena, usa le istanze.

8 Mesh LOD e istanze

LOD sta per linea di distanza. Questa funzione ti consente di specificare le mesh in base alla distanza del visualizzatore. Man mano che la distanza dal visualizzatore all'oggetto aumenta, il livello di dettaglio per la mesh viene mostrato chiaramente utilizzando il livello di dettaglio.

9 Mesh VolumemetricLightScatteringPost-process

Questo processo disperde la luce come mostrato nell'output fornito di seguito. Prova lo stesso nel browser e vedrai come la luce si diffonde attraverso la maglia.

10 Rendering di bordi in mesh

EdgesRendering è usato per disegnare egdes attorno alla mesh come mostrato nell'output sopra.

11 Mesh BlendModes

È possibile creare una modalità di fusione modificando l'alfabeto dei materiali.

12 Mesh SolidParticles

SolidParticle System viene aggiornato su una mesh. Tutte le proprietà che abbiamo visto su una mesh possono essere utilizzate sulla parte solida.

13 Mesh FacetData

I dati dei facet occupano molta memoria e questa funzione non è abilitata per impostazione predefinita. Per abilitarlo, dobbiamo creare una mesh come richiesto e aggiornarvi i dati del facet.