Skip to content

Commit f89199d

Browse files
authored
Merge pull request #172 from MageStudio/retrieving-hierarchy
retrieving hierarchy of the scene, updated names for lights, added ex…
2 parents 1f8d8f8 + 4b9645b commit f89199d

19 files changed

Lines changed: 303 additions & 24 deletions

File tree

examples/hierarchy/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<link href="https://fonts.googleapis.com/css2?family=Bangers&display=swap" rel="stylesheet">
6+
<link rel="stylesheet" href="../css/M.css" />
7+
<link rel="stylesheet" href="../css/app.css" />
8+
<script type="module" src="index.js"></script>
9+
</head>
10+
11+
<body>
12+
<div id="ui"></div>
13+
<div id="gameContainer" />
14+
</body>
15+
16+
</html>

examples/hierarchy/index.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import {
2+
Router,
3+
store,
4+
Level,
5+
Box,
6+
Scene,
7+
Cube,
8+
Controls,
9+
Models,
10+
AmbientLight,
11+
PHYSICS_EVENTS,
12+
constants,
13+
Scripts,
14+
PALETTES,
15+
SunLight,
16+
HemisphereLight,
17+
Color,
18+
Sky
19+
} from '../../dist/mage.js';
20+
21+
export default class Intro extends Level {
22+
23+
addAmbientLight() {
24+
const ambientLight = new AmbientLight({
25+
color: PALETTES.FRENCH_PALETTE.SPRAY,
26+
intensity: .5
27+
});
28+
29+
const hemisphereLight = new HemisphereLight({
30+
color: {
31+
sky: PALETTES.FRENCH_PALETTE.SQUASH_BLOSSOM,
32+
ground: PALETTES.FRENCH_PALETTE.REEF_ENCOUNTER
33+
},
34+
intensity: 1
35+
});
36+
37+
const sunLight = new SunLight({
38+
color: PALETTES.FRENCH_PALETTE.MELON_MELODY,
39+
intensity: 1,
40+
far: 20,
41+
mapSize: 2048
42+
});
43+
sunLight.setPosition({ y: 4, z: -3, x: -3 });
44+
sunLight.addHelper();
45+
}
46+
47+
createSky() {
48+
const sky = new Sky();
49+
const inclination = .1;
50+
const azimuth = .1;
51+
const distance = 100;
52+
53+
sky.setSun(
54+
inclination,
55+
azimuth,
56+
distance
57+
);
58+
}
59+
60+
createCube() {
61+
const size = 2;
62+
const color = Color.randomColor(true);
63+
const cube = new Cube(size, color);
64+
const position = {
65+
x: Math.random() * 30 - 15,
66+
z: Math.random() * 30 - 15,
67+
y: Math.random() * 10 + 10
68+
}
69+
70+
const rotation = {
71+
x: Math.random(),
72+
y: Math.random(),
73+
z: Math.random()
74+
}
75+
76+
cube.setPosition(position);
77+
cube.setRotation(rotation);
78+
cube.setWireframe(true);
79+
80+
return cube;
81+
}
82+
83+
onCreate() {
84+
Scene.getCamera().setPosition({ y: 10 });
85+
Controls.setOrbitControl();
86+
this.addAmbientLight();
87+
this.createSky();
88+
89+
const bottom = this.createCube();
90+
const other = this.createCube();
91+
other.add(bottom);
92+
const lonely = this.createCube();
93+
94+
console.log(Scene.getHierarchy());
95+
}
96+
}
97+
98+
const assets = {}
99+
100+
const { SHADOW_TYPES } = constants;
101+
102+
const config = {
103+
screen: {
104+
h: window ? window.innerHeight : 800,
105+
w: window ? window.innerWidth : 600,
106+
ratio: window ? window.innerWidth / window.innerHeight : 600 / 800,
107+
frameRate: 60,
108+
alpha: true,
109+
},
110+
111+
lights: {
112+
shadows: true,
113+
shadowType: SHADOW_TYPES.HARD,
114+
textureAnisotropy: 32
115+
},
116+
117+
physics: {
118+
enabled: true,
119+
path: 'dist/ammo.js',
120+
gravity: { x: 0, y: -9.8, z: 0}
121+
},
122+
123+
tween: {
124+
enabled: false,
125+
},
126+
127+
camera: {
128+
fov: 75,
129+
near: 0.1,
130+
far: 3000000,
131+
},
132+
};
133+
134+
window.addEventListener('load', () => {
135+
store.createStore({}, {}, true);
136+
137+
Router.on('/', Intro);
138+
139+
Router.start(config, assets);
140+
});

examples/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<li class='example' data-src='./physics'>Physics</li>
4343
<li class='example' data-src='./sound'>Clicky Sound</li>
4444
<li class='example' data-src='./trails'>Trails particles</li>
45+
<li class='example' data-src='./hierarchy'>hierarchy</li>
4546
<li class='example' data-src='./textures'>Textures</li>
4647
</ul>
4748
<iframe class='example-frame'></iframe>

src/controls/Transform.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export default class TransformControls extends Object3D {
124124

125125

126126
this.isTransformControls = true;
127-
Scene.add(this, this, false);
127+
Scene.add(this, null, false);
128128
}
129129

130130
render() {}

src/controls/TransformGizmo.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default class Gizmo extends Object3D {
4949
this.scaleHandleGeometry = new BoxBufferGeometry(0.125, 0.125, 0.125);
5050

5151
this.lineGeometry = new BufferGeometry();
52-
this.lineGeometry.addAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 0, 0], 3));
52+
this.lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 0, 0], 3));
5353

5454
// Make unique material for each axis/color
5555
this.matInvisible = this.gizmoMaterial.clone();
@@ -152,7 +152,7 @@ export default class Gizmo extends Object3D {
152152
vertices.push(0, Math.cos(i / 32 * Math.PI) * radius, Math.sin(i / 32 * Math.PI) * radius);
153153
}
154154

155-
geometry.addAttribute('position', new Float32BufferAttribute(vertices, 3));
155+
geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
156156

157157
return geometry;
158158
}
@@ -161,7 +161,7 @@ export default class Gizmo extends Object3D {
161161

162162
const geometry = new BufferGeometry()
163163

164-
geometry.addAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 1, 1], 3));
164+
geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 1, 1], 3));
165165

166166
return geometry;
167167
}
@@ -424,7 +424,7 @@ export default class Gizmo extends Object3D {
424424
object.updateMatrix();
425425

426426
var tempGeometry = object.geometry.clone();
427-
tempGeometry.applyMatrix(object.matrix);
427+
tempGeometry.applyMatrix4(object.matrix);
428428
object.geometry = tempGeometry;
429429

430430
object.position.set(0, 0, 0);

src/core/Level.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export class Level extends EventDispatcher {
3737
this.inputListenersAreSet = false;
3838
}
3939

40+
getName() {
41+
return this.name;
42+
}
43+
4044
prepareScene() {}
4145

4246
onStateChange = (state) => {};
@@ -138,7 +142,7 @@ export class Level extends EventDispatcher {
138142
path
139143
} = this.options;
140144

141-
Scene.create(path);
145+
Scene.create(this.getName());
142146
Scene.createCamera(new Camera());
143147
this.enableInput();
144148

src/core/Scene.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,24 @@ import { mapShadowTypeToShadowMap } from '../lights/utils';
1616
import { DEFAULT_OUTPUT_ENCODING, OUTPUT_ENCODINGS } from '../lib/constants';
1717
import Physics from '../physics';
1818
import { PHYSICS_EVENTS } from '../physics/messages';
19+
import { ENTITY_TYPES } from '../entities/constants';
1920
export class Scene {
2021

2122
constructor() {
2223
this.clock = new Clock();
2324
this.rendererElements = {};
25+
this.elements = [];
2426
this.clearColor = 0x000000;
2527
this.alpha = 1.0;
2628

2729
this.shadowType = mapShadowTypeToShadowMap(DEFAULT_SHADOWTYPE);
2830
}
2931

30-
createScene(name) {
32+
getEntityType() {
33+
return ENTITY_TYPES.SCENE;
34+
}
35+
36+
createScene(name = `LevelScene_${Math.random()}`) {
3137
const fog = Config.fog();
3238

3339
this.scene = new THREEScene();
@@ -40,6 +46,14 @@ export class Scene {
4046
}
4147
}
4248

49+
uuid() {
50+
return this.scene.uuid;
51+
}
52+
53+
getName() {
54+
return this.scene.name;
55+
}
56+
4357
getScene() {
4458
return this.scene;
4559
}
@@ -58,12 +72,29 @@ export class Scene {
5872

5973
add(body, element, addUniverse = true) {
6074
this.scene.add(body);
75+
if (element) {
76+
this.elements.push(element);
77+
}
78+
6179
if (addUniverse) {
62-
Universe.set(element.getName(), element);
63-
Universe.storeUUIDToElementNameReference(body.uuid, element.getName());
80+
const name = element.getName();
81+
Universe.set(name, element);
82+
Universe.storeUUIDToElementNameReference(body.uuid, name);
6483
}
6584
}
6685

86+
getHierarchy() {
87+
return [{
88+
element: this,
89+
children: [
90+
this.getCamera().getHierarchy(),
91+
...(this.elements
92+
.filter(e => !e.hasParent() && !e.isHelper())
93+
.map(e => e.getHierarchy()))
94+
]
95+
}];
96+
}
97+
6798
remove(body) {
6899
this.scene.remove(body);
69100
Universe.remove(body.name);

src/entities/Entity.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import Scripts from '../scripts/Scripts';
1717
import {
1818
DEFAULT_TAG,
1919
ENTITY_EVENTS,
20-
ENTITY_TYPES
20+
ENTITY_TYPES,
21+
FLAT_ENTITY_TYPES
2122
} from './constants';
2223

2324
export default class Entity extends EventDispatcher {
@@ -50,10 +51,23 @@ export default class Entity extends EventDispatcher {
5051
this.body = body;
5152
}
5253

54+
hasParent() {
55+
return !!this.parent;
56+
}
57+
58+
getParent() {
59+
return this.parent;
60+
}
61+
62+
setParent(parent) {
63+
this.parent = parent;
64+
}
65+
5366
add(element) {
5467
if (this.hasBody()) {
5568
const _add = (toAdd) => {
5669
this.children.push(toAdd);
70+
toAdd.setParent(this);
5771
this.getBody()
5872
.add(toAdd.getBody());
5973
};
@@ -92,6 +106,13 @@ export default class Entity extends EventDispatcher {
92106
}
93107
}
94108

109+
getHierarchy() {
110+
return {
111+
element: this,
112+
children: this.children.map(e => e.getHierarchy())
113+
}
114+
}
115+
95116
addTag = (tagName) => {
96117
if (!tagName) return;
97118

@@ -291,7 +312,7 @@ export default class Entity extends EventDispatcher {
291312
}
292313

293314
setEntityType(type) {
294-
if (Object.values(ENTITY_TYPES).includes(type)) {
315+
if (FLAT_ENTITY_TYPES.includes(type)) {
295316
this.entityType = type;
296317
} else {
297318
console.log(ENTITY_TYPE_NOT_ALLOWED);
@@ -304,11 +325,13 @@ export default class Entity extends EventDispatcher {
304325
}
305326

306327
isMesh = () => this.getEntityType() === ENTITY_TYPES.MESH;
307-
isLight = () => this.getEntityType() === ENTITY_TYPES.LIGHT;
308328
isModel = () => this.getEntityType() === ENTITY_TYPES.MODEL;
309329
isSprite = () => this.getEntityType() === ENTITY_TYPES.SPRITE;
330+
isLight = () => Object.values(ENTITY_TYPES.LIGHT).includes(this.getEntityType());
331+
isHelper = () => Object.values(ENTITY_TYPES.HELPER).includes(this.getEntityType());
332+
isEffect = () => Object.values(ENTITY_TYPES.EFFECT).includes(this.getEntityType());
310333

311-
// TODO: sounds should become like particle emitters
334+
// TODO: sounds should become entities
312335
// addSound(name, options) {
313336
// const { autoplay = false, ...opts } = options;
314337

src/entities/base/Grid.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ export default class Grid extends Element {
99
size,
1010
division,
1111
color1,
12-
color2
12+
color2,
13+
name: `GridHelper_${Math.random()}`
1314
};
1415

1516
super(null, null, options);
1617
const body = new GridHelper(size, division, color1, color2);
1718

1819
this.setBody({ body });
19-
this.setEntityType(ENTITY_TYPES.MESH);
20+
this.setEntityType(ENTITY_TYPES.HELPER.GRID);
2021
}
2122

2223
update() {}

0 commit comments

Comments
 (0)