Skip to content

Commit 7f794cf

Browse files
committed
Merge branch 'dev' into IR-5373-Replace-GroupComponent-with-ObjectComponent-and-make-single-non-array-object
2 parents 818ed93 + 656cd77 commit 7f794cf

File tree

4 files changed

+217
-1
lines changed

4 files changed

+217
-1
lines changed

src/examples/ShadowExample.tsx

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import { GLTF } from '@gltf-transform/core'
2+
import {
3+
Entity,
4+
EntityUUID,
5+
UUIDComponent,
6+
UndefinedEntity,
7+
getComponent,
8+
removeEntity,
9+
setComponent,
10+
useOptionalComponent
11+
} from '@ir-engine/ecs'
12+
import { GLTFAssetState, GLTFSourceState } from '@ir-engine/engine/src/gltf/GLTFState'
13+
import { RenderSettingsComponent } from '@ir-engine/engine/src/scene/components/RenderSettingsComponent'
14+
import { ShadowComponent } from '@ir-engine/engine/src/scene/components/ShadowComponent'
15+
import { getMutableState, none, useHookstate, useMutableState } from '@ir-engine/hyperflux'
16+
import {
17+
DirectionalLightComponent,
18+
PointLightComponent,
19+
SpotLightComponent,
20+
TransformComponent
21+
} from '@ir-engine/spatial'
22+
import { EngineState } from '@ir-engine/spatial/src/EngineState'
23+
import { NameComponent } from '@ir-engine/spatial/src/common/NameComponent'
24+
import { RendererComponent } from '@ir-engine/spatial/src/renderer/WebGLRendererSystem'
25+
import { addObjectToGroup } from '@ir-engine/spatial/src/renderer/components/GroupComponent'
26+
import { MeshComponent } from '@ir-engine/spatial/src/renderer/components/MeshComponent'
27+
import { SceneComponent } from '@ir-engine/spatial/src/renderer/components/SceneComponents'
28+
import { VisibleComponent } from '@ir-engine/spatial/src/renderer/components/VisibleComponent'
29+
import React, { useEffect } from 'react'
30+
import { BoxGeometry, Cache, Color, Euler, Mesh, MeshLambertMaterial, Quaternion, Vector3 } from 'three'
31+
import { useExampleEntity } from './utils/common/entityUtils'
32+
33+
const createSceneGLTF = (id: string): GLTF.IGLTF => ({
34+
asset: {
35+
version: '2.0',
36+
generator: 'iR Engine'
37+
},
38+
scenes: [{ nodes: [] }],
39+
scene: 0,
40+
nodes: [],
41+
extensionsUsed: []
42+
})
43+
44+
const SceneReactor = (props: { sceneEntity: Entity }) => {
45+
const settingsEntity = useExampleEntity(props.sceneEntity)
46+
const platformEntity = useExampleEntity(props.sceneEntity)
47+
const boxEntity = useExampleEntity(props.sceneEntity)
48+
const directionalLightEntity = useExampleEntity(props.sceneEntity)
49+
const spotLightEntity = useExampleEntity(props.sceneEntity)
50+
const pointLightEntity = useExampleEntity(props.sceneEntity)
51+
52+
useEffect(() => {
53+
setComponent(settingsEntity, RenderSettingsComponent, {
54+
primaryLight: getComponent(directionalLightEntity, UUIDComponent)
55+
}) // required for CSM
56+
setComponent(platformEntity, TransformComponent, {
57+
position: new Vector3(0, -0.5, 0),
58+
scale: new Vector3(10, 0.1, 10)
59+
})
60+
setComponent(platformEntity, VisibleComponent)
61+
setComponent(platformEntity, NameComponent, 'Platform')
62+
setComponent(platformEntity, MeshComponent, new Mesh(new BoxGeometry(), new MeshLambertMaterial()))
63+
addObjectToGroup(platformEntity, getComponent(platformEntity, MeshComponent))
64+
setComponent(platformEntity, ShadowComponent, { cast: false })
65+
66+
setComponent(boxEntity, TransformComponent, { position: new Vector3(0, 0.5, 0) })
67+
setComponent(boxEntity, VisibleComponent)
68+
setComponent(boxEntity, NameComponent, 'Box')
69+
setComponent(boxEntity, MeshComponent, new Mesh(new BoxGeometry(), new MeshLambertMaterial()))
70+
addObjectToGroup(boxEntity, getComponent(boxEntity, MeshComponent))
71+
setComponent(boxEntity, ShadowComponent, { receive: false })
72+
73+
setComponent(directionalLightEntity, TransformComponent, {
74+
position: new Vector3(1, 2, -3),
75+
rotation: new Quaternion().setFromEuler(
76+
new Euler().setFromVector3(new Vector3(Math.PI * 0.5, -Math.PI * 0.25).normalize())
77+
)
78+
})
79+
setComponent(directionalLightEntity, NameComponent, 'Directional Light')
80+
setComponent(directionalLightEntity, VisibleComponent)
81+
setComponent(directionalLightEntity, DirectionalLightComponent, {
82+
intensity: 0.5,
83+
castShadow: true,
84+
color: new Color('cyan')
85+
})
86+
setComponent(directionalLightEntity, ShadowComponent, { receive: false })
87+
88+
setComponent(spotLightEntity, TransformComponent, {
89+
position: new Vector3(1, 2, 2),
90+
rotation: new Quaternion().setFromEuler(
91+
new Euler().setFromVector3(new Vector3(Math.PI * 0.75, -Math.PI * 0.1, 0))
92+
)
93+
})
94+
setComponent(spotLightEntity, NameComponent, 'Spot Light')
95+
setComponent(spotLightEntity, VisibleComponent)
96+
setComponent(spotLightEntity, SpotLightComponent, {
97+
castShadow: true,
98+
decay: 1,
99+
range: 10,
100+
intensity: 10,
101+
color: new Color('green')
102+
})
103+
104+
setComponent(pointLightEntity, TransformComponent, { position: new Vector3(0, 2, -2) })
105+
setComponent(pointLightEntity, NameComponent, 'Point Light')
106+
setComponent(pointLightEntity, VisibleComponent)
107+
setComponent(pointLightEntity, PointLightComponent, {
108+
castShadow: true,
109+
decay: 2,
110+
range: 5,
111+
intensity: 10,
112+
color: new Color('red')
113+
})
114+
}, [])
115+
116+
return <></>
117+
}
118+
119+
export default function ShadowExampleEntry() {
120+
const entity = useHookstate(UndefinedEntity)
121+
const engine = useMutableState(EngineState)
122+
const renderer = useOptionalComponent(engine.viewerEntity.value, RendererComponent)
123+
124+
useEffect(() => {
125+
if (!renderer?.value) return
126+
127+
const sceneID = `scene`
128+
const gltf = createSceneGLTF(sceneID)
129+
130+
const sceneURL = `/${sceneID}.gltf`
131+
132+
Cache.add(sceneURL, gltf)
133+
134+
const gltfEntity = GLTFSourceState.load(sceneURL, sceneURL as EntityUUID)
135+
renderer.scenes.merge([gltfEntity])
136+
setComponent(gltfEntity, SceneComponent)
137+
getMutableState(GLTFAssetState)[sceneURL].set(gltfEntity)
138+
139+
entity.set(gltfEntity)
140+
141+
return () => {
142+
const idx = renderer.scenes.value.indexOf(gltfEntity)
143+
renderer.scenes[idx].set(none)
144+
removeEntity(gltfEntity)
145+
}
146+
}, [!!renderer?.scenes.value])
147+
148+
if (!entity.value) return null
149+
150+
return <SceneReactor sceneEntity={entity.value} />
151+
}

src/examples/componentExamples/componentExamples.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import config from '@ir-engine/common/src/config'
22
import {
3+
Easing,
34
Entity,
45
UUIDComponent,
56
UndefinedEntity,
@@ -34,6 +35,7 @@ import { useHookstate } from '@ir-engine/hyperflux'
3435
import { TransformComponent } from '@ir-engine/spatial'
3536
import { CallbackComponent } from '@ir-engine/spatial/src/common/CallbackComponent'
3637
import { NameComponent } from '@ir-engine/spatial/src/common/NameComponent'
38+
import { Q_IDENTITY, Q_Y_180 } from '@ir-engine/spatial/src/common/constants/MathConstants'
3739
import { setVisibleComponent } from '@ir-engine/spatial/src/renderer/components/VisibleComponent'
3840
import { ObjectLayerMasks } from '@ir-engine/spatial/src/renderer/constants/ObjectLayers'
3941
import { EntityTreeComponent } from '@ir-engine/spatial/src/transform/components/EntityTree'
@@ -79,6 +81,63 @@ export const subComponentExamples = [
7981
return null
8082
}
8183
},
84+
{
85+
name: 'Transitions',
86+
description: 'Add transitions to your scene',
87+
Reactor: (props: { parent: Entity; onLoad: (entity: Entity) => void }) => {
88+
const { parent, onLoad } = props
89+
const entity = useExampleEntity(parent)
90+
const gltfComponent = useOptionalComponent(entity, GLTFComponent)
91+
92+
useEffect(() => {
93+
setComponent(entity, NameComponent, 'Transition-Example')
94+
setComponent(entity, GLTFComponent, {
95+
cameraOcclusion: true,
96+
src:
97+
config.client.fileServer +
98+
'/projects/ir-engine/ir-development-test-suite/assets/GLTF/Flight%20Helmet/FlightHelmet.gltf'
99+
})
100+
setVisibleComponent(entity, true)
101+
getComponent(entity, TransformComponent).scale.set(3, 3, 3)
102+
103+
let id: any
104+
105+
const transitionA = () => {
106+
TransformComponent.setTransition(entity, 'position.y', 2, {
107+
duration: 1000,
108+
easing: Easing.exponential.inOut
109+
})
110+
TransformComponent.setTransition(entity, 'rotation', Q_Y_180, {
111+
duration: 500,
112+
easing: Easing.exponential.inOut
113+
})
114+
id = setTimeout(transitionB, 1000)
115+
}
116+
117+
const transitionB = () => {
118+
TransformComponent.setTransition(entity, 'position.y', 0, {
119+
duration: 1000,
120+
easing: Easing.exponential.inOut
121+
})
122+
TransformComponent.setTransition(entity, 'rotation', Q_IDENTITY, {
123+
duration: 500,
124+
easing: Easing.exponential.inOut
125+
})
126+
id = setTimeout(transitionA, 1000)
127+
}
128+
129+
transitionA()
130+
131+
return () => clearTimeout(id)
132+
}, [])
133+
134+
useEffect(() => {
135+
if (gltfComponent?.progress.value === 100) onLoad(entity)
136+
}, [gltfComponent?.progress])
137+
138+
return null
139+
}
140+
},
82141
{
83142
name: 'Avatars',
84143
description: 'Add avatars to your scene',

src/examplesRoute.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import MultipleCanvasCameras from './examples/MultipleCanvasCameras'
99
import MultipleCanvasScenes from './examples/MultipleCanvasScenes'
1010
import P2PConnection from './examples/P2PConnection'
1111
import PhysicsDynamicObjects from './examples/PhysicsDynamicObjects'
12+
import ShadowExampleEntry from './examples/ShadowExample'
1213
import AvatarMocapEntry from './examples/avatarMocap'
1314
import AvatarSimpleEntry from './examples/avatarSimple'
1415
import AvatarTestEntry from './examples/avatarTest'
@@ -78,6 +79,11 @@ export const examples: RouteCategories = [
7879
{
7980
category: 'Scene',
8081
routes: [
82+
{
83+
name: 'Shadows',
84+
description: 'Cast shadows from directional, point, and spot lights',
85+
entry: ShadowExampleEntry
86+
},
8187
{
8288
name: 'GLTF Viewer',
8389
description: 'Drag and drop GLTF files',

src/sceneRoute.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { SearchParamState } from '@ir-engine/client-core/src/common/services/Rou
77
import Debug from '@ir-engine/client-core/src/components/Debug'
88
import { useNetwork } from '@ir-engine/client-core/src/components/World/EngineHooks'
99
import { useLoadScene } from '@ir-engine/client-core/src/components/World/LoadLocationScene'
10-
import { useEngineCanvas } from '@ir-engine/client-core/src/hooks/useEngineCanvas'
1110
import { useLoadedSceneEntity } from '@ir-engine/client-core/src/hooks/useLoadedSceneEntity'
1211
import { LocationState } from '@ir-engine/client-core/src/social/services/LocationService'
1312
import '@ir-engine/client-core/src/world/LocationModule'
@@ -26,6 +25,7 @@ import {
2625
} from '@ir-engine/hyperflux'
2726
import { EngineState } from '@ir-engine/spatial/src/EngineState'
2827
import { useSpatialEngine } from '@ir-engine/spatial/src/initializeEngine'
28+
import { useEngineCanvas } from '@ir-engine/spatial/src/renderer/functions/useEngineCanvas'
2929
import Button from '@ir-engine/ui/src/primitives/tailwind/Button'
3030
import { HiChevronDown, HiChevronLeft, HiChevronRight, HiChevronUp } from 'react-icons/hi2'
3131

0 commit comments

Comments
 (0)