Let’s make some 3D in Svelte: physics and more

Photo by DeepMind on Unsplash

In the last article of this small series, we took a look at a very fascinating part of the 3D worlds: the physics. This is also possible with Threlte. But here, I need to warn you. At the point of writing this article, the support for physics is still at a very early stage. I can confirm this based on my own experience. That’s why there can be errors as well as problems and also changes in the API in the near future. This beside, let’s start.

We are still using the scene of the last two articles. Now we want to drop a box into our model. In order to do this, we need to introduce two new terms: Colliders and Rigid Body.

Collider

Colliders are bodies with which the computer calculates the collision and intersection with other bodies. With a box, the collider takes the form of a box, which is also very intuitive. But with more complex shapes like our island, things look different. The math behind the collision tends to be really complex and computational intensive (that is why collision are a common area for glitches and bugs). This problem gets only worse with more complex objects. That’s why we want to try to take simplified shapes. Therefore, we need to add colliders manually.

Rigidbody

Then there are the rigidbodies. These are simply objects on which physical forces can act. This is e.g. the case with gravitation. A rigidbody needs a collider, or otherwise it will not be visible to the computer in questions of collision.

Before we can implement everything, we need to make a few modifications to our App.svelte file. Besides a canvas, we need a world where the physics can take place.

<Canvas size={{ width: 1280, height: 720 }}>
    <World>
      <Debug />
      <Scene />
    </World>
</Canvas>

Now we can really start. First, we add a box. It can send and receive shadows. This box will be positioned at an height of 8. However, we need to do this in the rigidbody component. It gets the type „dynamic“ and the position of 8 on the y-axis. We also add an autocollider. This one has the shape „cuboid“ and the args={[0.5,0.5,0.5]}
This is what it all looks like together:

<RigidBody type={"dynamic"} position={{ y: 7 }}>
  <Collider
    shape={"cuboid"}
    args={[0.5, 0.5, 0.5]}
  />
  <Mesh
    receiveShadow
    castShadow
    geometry={new BoxBufferGeometry(1, 1, 1)}
    material={new MeshStandardMaterial({ side: DoubleSide, color: "white" })}
  />
</RigidBody>

If we now run it in the browser, the cube falls through the floor. This is because the remaining two objects do not have colliders. Let’s change that now.
The ground also gets a autocollider with the type trimesh, but no rigidbody. For the island, on the other hand, the type of the autocollider is convexHull. This is a collider type that calculates a simplified shape of the object.

{#if island != null}
  <Group position={{ y: 0.5 }}>
      <AutoColliders shape={"convexHull"} >
        <Mesh
          interactive
          recieveShadow
          castShadow
          geometry={island.children[0].geometry}
          material={new MeshStandardMaterial()}
        />
      </AutoColliders>
  </Group>
{/if}
<AutoColliders shape={"trimesh"} position={{ y: -0.5 }}>
  <!-- Floor -->
  <Mesh
    receiveShadow
    rotation={{ x: -90 * (Math.PI / 180) }}
    geometry={new CircleBufferGeometry(4, 72)}
    material={new MeshStandardMaterial({ side: DoubleSide, color: "white" })}
  />
</AutoColliders>

Now we have everything together. We have a finished scene of objects.

Here is the code of this article:

https://gist.github.com/ngarske/02ba240409cf341310bea19cc3ccd4e7


Beitrag veröffentlicht

in

,

von

Schlagwörter:

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert