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