Skip to main content

Hello World

In this tutorial we will build an app that introduces basics of using meep.

By the end of the tutorial you will have an app with:

  • 3d model
  • lights
  • camera
  • character controller

Prerequisites

You an empty meep project prepared, following the setup instructions.

Initial Setup

To start with, we will initialize the engine

const engine = new Engine();

engine.start();

We will want to add some systems to enable functionality that we're going to use

const entityManager: EntityManager = engine.entityManager;

entityManager.addSystem(new ShadedGeometrySystem(engine)); // enable us to draw 3d objects
entityManager.addSystem(new CameraSystem(engine.graphics)); // camera support
entityManager.addSystem(new LightSystem(engine.graphics)); // lights
engityManager.addSystem(new InputControllerSystem(engine.devices));

Next we need a scene

const scene: Scene = engine.sceneManager.create("world");
engine.sceneManager.set("world"); // set our scene as current

Populating the world

Finally, done with the setup, we can go ahead and create some objects, lets add a camera and a light

// camera
new Entity()
.add(new Camera())
.add(Transform.fromJSON({
position: {x: 0, y: 0, z: -10}
}))
.build(scene.dataset);

// light
new Entity()
.add(Light.fromJSON({
type: LightType.DIRECTION
}))
.add(new Transform())
.build(scene.dataset);

Let's go ahead and create a sphere

const sphere_transform = new Transform(); // assign to a variable for later use

const sphere = new Entity()
.add(sphere_transform)
.add(ShadedGeometry.from(
new SphereGeometry(1),
new MeshStandardMaterial({color: "white"})
));

sphere.build(scene.dataset);

Adding interactivity

Now we can add a bit of interactivity to the scene

sphere.add(new InputController([
{
path: "keyboard/keys/left_arrow/down",
listener: () => sphere_transform.position._add(-1, 0, 0)
},
{
path: "keyboard/keys/right_arrow/down",
listener: () => sphere_transform.position._add(+1, 0, 0)
},
{
path: "keyboard/keys/up_arrow/down",
listener: () => sphere_transform.position._add(0, -1, 0)
},
{
path: "keyboard/keys/down_arrow/down",
listener: () => sphere_transform.position._add(0, +1, 0)
}
]));

With this we have a complete app, and we can move our sphere around with arrow keys on the keyboard.

As a bonus, lets make the sphere grow in size when we tap/click on the screen.

sphere.add(new InputController([
// ...
{
path: "pointer/on/tap",
listener: () => sphere_transform.scale.multiplyScalar(1.05)
}
]));

Complete Solution

And here is the complete source code

///////////////////
// -- Imports -- //
///////////////////

// Components
import {Transform} from "@woosh/meep-engine/src/engine/ecs/transform/Transform";
import {Camera} from "@woosh/meep-engine/src/engine/graphics/ecs/camera/Camera";
import {Light} from "@woosh/meep-engine/src/engine/graphics/ecs/light/Light";
import {LightType} from "@woosh/meep-engine/src/engine/graphics/ecs/light/LightType";
import {ShadedGeometry} from "@woosh/meep-engine/src/engine/graphics/ecs/mesh-v2/ShadedGeometry";
import InputController from "@woosh/meep-engine/src/engine/input/ecs/components/InputController";

// Systems
import {CameraSystem} from "@woosh/meep-engine/src/engine/graphics/ecs/camera/CameraSystem";
import LightSystem from "@woosh/meep-engine/src/engine/graphics/ecs/light/LightSystem";
import {ShadedGeometrySystem} from "@woosh/meep-engine/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem";
import InputControllerSystem from "@woosh/meep-engine/src/engine/input/ecs/systems/InputControllerSystem";

// Misc
import Entity from "@woosh/meep-engine/src/engine/ecs/Entity";
import Engine from "@woosh/meep-engine/src/engine/Engine";
import {EntityComponentDataset} from "@woosh/meep-engine/src/engine/ecs/EntityComponentDataset";
import {EntityManager} from "@woosh/meep-engine/src/engine/ecs/EntityManager";
import {SphereGeometry, MeshStandardMaterial} from "three"

/////////////////////////////////
// -- Engine Initialization -- //
/////////////////////////////////

const engine = new Engine();

const entityManager: EntityManager = engine.entityManager;

entityManager.addSystem(new ShadedGeometrySystem(engine)); // enable us to draw 3d objects
entityManager.addSystem(new CameraSystem(engine.graphics)); // camera support
entityManager.addSystem(new LightSystem(engine.graphics)); // lights
engityManager.addSystem(new InputControllerSystem(engine.devices));

engine.start();

const scene: Scene = engine.sceneManager.create("world");
engine.sceneManager.set("world"); // set our scene as current

const dataset: EntityComponentDataset = scene.dataset;

////////////////////////////
// -- World Population -- //
////////////////////////////

// camera
new Entity()
.add(new Camera())
.add(Transform.fromJSON({
position: {x: 0, y: 0, z: -10}
}))
.build(dataset);

// light
new Entity()
.add(Light.fromJSON({
type: LightType.DIRECTION
}))
.add(new Transform())
.build(dataset);

const sphere_transform = new Transform();

const sphere = new Entity()
.add(sphere_transform)
.add(ShadedGeometry.from(
new SphereGeometry(1),
new MeshStandardMaterial({color: "white"})
))
.add(new InputController([
{
path: "keyboard/keys/left_arrow/down",
listener: () => sphere_transform.position._add(-1, 0, 0)
},
{
path: "keyboard/keys/right_arrow/down",
listener: () => sphere_transform.position._add(+1, 0, 0)
},
{
path: "keyboard/keys/up_arrow/down",
listener: () => sphere_transform.position._add(0, -1, 0)
},
{
path: "keyboard/keys/down_arrow/down",
listener: () => sphere_transform.position._add(0, +1, 0)
},
{
path: "pointer/on/tap",
listener: () => sphere_transform.scale.multiplyScalar(1.05)
}
]));

sphere.build(dataset);