Skip to content

Commit 8d6910f

Browse files
authored
Merge pull request #40 from trenc/feat/groupAndClone
feat: support grouping and cloning
2 parents b49b980 + be34b1d commit 8d6910f

File tree

6 files changed

+315
-20
lines changed

6 files changed

+315
-20
lines changed

dist/klee.js

+33-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// src/modules/constants.js
2-
var KLEEVERSION = "0.8.3";
2+
var KLEEVERSION = "0.9.0";
33

44
// src/default.options.js
55
function getDefaultOptions(THREE) {
@@ -606,6 +606,9 @@ var Item = /* @__PURE__ */ function() {
606606
if (options.geometry) {
607607
return addMesh(options);
608608
}
609+
if (options.cloneOf) {
610+
return addClone(options);
611+
}
609612
}
610613
const items = [];
611614
if (Array.isArray(options)) {
@@ -616,21 +619,47 @@ var Item = /* @__PURE__ */ function() {
616619
}
617620
return items;
618621
}
622+
function addClone(options) {
623+
const source = App.scene.getObjectByName(options.cloneOf);
624+
if (!source || !source.isObject3D) {
625+
return null;
626+
}
627+
let clone = source.clone(true);
628+
clone = change(clone, options);
629+
addToScene(clone, options);
630+
return clone;
631+
}
619632
async function addFromLoader(options) {
620633
let item = await Loaders.load(options);
621634
if (item.scene) {
622635
let parent = wrapGroupParent(item.scene, options);
623636
parent = change(parent, options);
624637
parent.receiveShadow = false;
625638
parent.castShadow = false;
626-
App.scene.add(parent);
639+
addToScene(parent, options);
627640
return parent;
628641
} else {
629642
item = change(item, options);
630-
App.scene.add(item);
643+
addToScene(item, options);
631644
return item;
632645
}
633646
}
647+
function addToScene(item, options) {
648+
const THREE = App.THREE;
649+
if (!options.group) {
650+
App.scene.add(item);
651+
return;
652+
}
653+
let group = App.scene.getObjectByName(options.group);
654+
if (group) {
655+
group.add(item);
656+
return;
657+
}
658+
group = new THREE.Group();
659+
group.name = options.group;
660+
group.add(item);
661+
App.scene.add(group);
662+
}
634663
function wrapGroupParent(item, options) {
635664
const THREE = App.THREE;
636665
const box = new THREE.Box3().setFromObject(item);
@@ -668,7 +697,7 @@ var Item = /* @__PURE__ */ function() {
668697
}
669698
function addMesh(options) {
670699
const mesh = create(options);
671-
App.scene.add(mesh);
700+
addToScene(mesh, options);
672701
return mesh;
673702
}
674703
function change(object, options) {

example/grouping-and-cloning.html

+230
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<title>klee.js - drag on ground</title>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<link rel="stylesheet" href="css/styles.css" />
8+
</head>
9+
<body>
10+
11+
<script type="importmap">
12+
{
13+
"imports": {
14+
"three": "./libs/three.module.min.js",
15+
"klee": "./../dist/klee.js"
16+
}
17+
}
18+
</script>
19+
20+
<script type="module">
21+
22+
import * as THREE from 'three';
23+
import { OrbitControls } from './libs/jsm/controls/OrbitControls.js';
24+
import * as KLEE from 'klee';
25+
26+
// for preloading wrap all in an async function
27+
(async () => {
28+
29+
// some opinionated default options declared in /src/default.options.js
30+
// you can overwrite these here or add additional options
31+
const options = {
32+
33+
debugLevel: 3,
34+
35+
renderer: {
36+
clearColor: '#103c48'
37+
},
38+
39+
camera: {
40+
properties: {
41+
position: { x: -2, z: 10 }
42+
}
43+
}
44+
45+
};
46+
47+
const orbitControlsOptions = {
48+
// no type and args here, we need the object direct
49+
// and args (camera, renderElement are given)
50+
properties: {
51+
//autoRotate: true,
52+
enableDampling: true,
53+
enablePan: true,
54+
dampingFactor: 0.25,
55+
enableZoom: true,
56+
minDistance: 5,
57+
maxDistance: 30,
58+
minPolarAngle: 0.1,
59+
maxPolarAngle: 1.5
60+
}
61+
62+
};
63+
64+
const lights = [
65+
{
66+
type: 'AmbientLight',
67+
properties: {
68+
name: 'light-1',
69+
intensity: 2,
70+
color: '#404040'
71+
}
72+
},
73+
{
74+
type: 'DirectionalLight',
75+
properties: {
76+
name: 'light-2',
77+
color: '#ffffff',
78+
intensity: 3,
79+
castShadow: true,
80+
shadow: { mapSize: { x: 2048, y: 2048 } }, // INFO: x,y instead of width, height
81+
position: { x: 30, y: 30, z: 30 }
82+
}
83+
},
84+
{
85+
type: 'DirectionalLight',
86+
properties: {
87+
name: 'light-3',
88+
color: '#ffffff',
89+
intensity: 1,
90+
position: { x: -30, y: 30, z: -30 }
91+
}
92+
}
93+
];
94+
95+
const items = [ // aka meshs
96+
{
97+
geometry: {
98+
type: 'PlaneGeometry',
99+
args: [16, 16]
100+
},
101+
material: {
102+
type: 'MeshStandardMaterial',
103+
properties: {
104+
color: '#103c48'
105+
},
106+
},
107+
properties: {
108+
receiveShadow: true,
109+
rotation: { x: Math.PI / -2 },
110+
name: 'Floor',
111+
userData: {
112+
movingLimiter: true
113+
}
114+
}
115+
},
116+
{
117+
group: 'BoxGroup',
118+
geometry: {
119+
type: 'BoxGeometry',
120+
args: [1, 1, 1]
121+
},
122+
material: {
123+
type: 'MeshStandardMaterial',
124+
textures: [
125+
{
126+
map: 'map',
127+
url: './textures/Wood060_1K_Color.jpg'
128+
},
129+
{
130+
map: 'normalMap',
131+
url: './textures/Wood060_1K_Normal.jpg',
132+
properties: {
133+
flipY: false
134+
}
135+
},
136+
{
137+
map: 'roughnessMap',
138+
url: './textures/Wood060_1K_Roughness.jpg'
139+
},
140+
{
141+
map: 'aoMap',
142+
url: './textures/Wood060_1K_AmbientOcclusion.jpg'
143+
},
144+
{
145+
map: 'bumpMap',
146+
url: './textures/Wood060_1K_Displacement.jpg'
147+
}
148+
]
149+
},
150+
properties: {
151+
name: 'some box 1',
152+
rotation: { y: Math.PI / 8 },
153+
position: { x: -0.5, y: 0.5, z: -0.5 },
154+
castShadow: true,
155+
receiveShadow: true,
156+
userData: {
157+
draggable: true,
158+
dragMaterial: {
159+
type: 'MeshStandardMaterial',
160+
properties: {
161+
color: 0xfa5750,
162+
transparent: true,
163+
opacity: 0.6
164+
}
165+
}
166+
}
167+
}
168+
},
169+
{
170+
cloneOf: 'some box 1',
171+
group: 'BoxGroup',
172+
properties: {
173+
name: 'some box 2',
174+
rotation: { y: Math.PI / 3 },
175+
position: { x: 0.75, y: 1.5, z: -0.5 },
176+
castShadow: true,
177+
receiveShadow: true,
178+
userData: {
179+
draggable: true,
180+
dragMaterial: {
181+
type: 'MeshStandardMaterial',
182+
properties: {
183+
color: 0x104830,
184+
transparent: true,
185+
opacity: 0.6
186+
}
187+
}
188+
}
189+
}
190+
}
191+
];
192+
193+
const gridHelper = {
194+
type: 'GridHelper',
195+
args: [50, 50, '#72898f', '#72898f']
196+
};
197+
198+
// initalize app
199+
KLEE.App.init(THREE, options);
200+
201+
// initalize scene
202+
KLEE.Scene.init();
203+
204+
// optional controls
205+
KLEE.Controls.init(OrbitControls, orbitControlsOptions);
206+
207+
// optional events
208+
KLEE.Events.init();
209+
210+
// shed some light
211+
KLEE.Light.add(lights);
212+
213+
// add a boxes
214+
KLEE.Item.add(items);
215+
216+
// add a grid
217+
KLEE.Object3d.add(gridHelper);
218+
219+
// run the app after loading
220+
KLEE.App.manager.onLoad = () => KLEE.App.run();
221+
222+
// inspect the scene in console
223+
console.log(KLEE.App.scene.getObjectByName('BoxGroup'));
224+
225+
})();
226+
227+
</script>
228+
229+
</body>
230+
</html>

example/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ <h1>Examples</h1>
2020
<li><a href="./gltf-loader.html">GLTF Loader</a></li>
2121
<li><a href="./collision-detection.html">Collision Detection</a></li>
2222
<li><a href="./callbacks.html">Callbacks</a></li>
23+
<li><a href="./grouping-and-cloning.html">Grouping and Cloning</a></li>
2324
</ul>
2425

2526
</main>

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "klee.js",
3-
"version": "0.8.3",
3+
"version": "0.9.0",
44
"main": "src/klee.js",
55
"private": true,
66
"type": "module",

src/modules/constants.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
const KLEEVERSION = '0.8.3';
1+
const KLEEVERSION = '0.9.0';
22

33
export { KLEEVERSION };

0 commit comments

Comments
 (0)