Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
loader: "awesome-typescript-loader",
},
{
test: /\.(glb|mtl|png|jpe?g|gif)$/,
test: /\.(glb|mtl|png|jpe?g|gif|hdr|exr)$/,
use: [
{
loader: "file-loader",
Expand Down
11 changes: 3 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/builders/GameBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LoadingManager } from "three"
import { LoadingManager, WebGLRenderer } from "three"

import CameraManager from "../managers/CameraManager"
import DataManager from "../managers/DataManager"
Expand Down Expand Up @@ -26,14 +26,16 @@ const defaultGameBuilder = async ({
defaultLoadouts
}: GameBuilderOptions) => {
const players = replayMetadata.players
const sceneManager = await defaultSceneBuilder(players, loadingManager, defaultLoadouts)
const renderer = new WebGLRenderer({ antialias: true })
const sceneManager = await defaultSceneBuilder(players, renderer, loadingManager, defaultLoadouts)
defaultAnimationBuilder(replayData, sceneManager.players, sceneManager.ball)
DataManager.init({ replayData, replayMetadata })
CameraManager.init()
KeyManager.init()

return GameManager.init({
clock,
renderer
})
}

Expand Down
17 changes: 10 additions & 7 deletions src/builders/SceneBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RocketAssetManager, RocketConfig, TextureFormat } from "rl-loadout-lib"
import { Cache, LoadingManager, Scene } from "three"
import { Cache, LoadingManager, Scene, WebGLRenderer } from "three"
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"

Expand All @@ -11,6 +11,7 @@ import { buildBall } from "./ball/buildBall"
import { buildPlayfield } from "./field/buildPlayfield"
import { buildRocketLoadoutGroup } from "./player/buildRocketLoadoutScene"
import { addLighting } from "./scene/addLighting"
import { addEnvironment } from "./scene/addEnvironment";

/**
* @description The sole purpose of this function is to initialize and tie together all of the
Expand All @@ -20,6 +21,7 @@ import { addLighting } from "./scene/addLighting"
*/
const defaultSceneBuilder = async (
playerInfo: ExtendedPlayer[],
renderer: WebGLRenderer,
loadingManager?: LoadingManager,
defaultLoadouts?: boolean
): Promise<SceneManager> => {
Expand All @@ -44,17 +46,18 @@ const defaultSceneBuilder = async (
useCompressedModels: true,
})
const manager = new RocketAssetManager(config)
const bodyPromises = playerInfo.map(player =>
loadRlLoadout(manager, player, defaultLoadouts)
)

await GameFieldAssets.load()
const bodies = await Promise.all(bodyPromises)

addLighting(scene)
const field = buildPlayfield(scene)
const envMap = addEnvironment(scene, renderer)
const bodyPromises = playerInfo.map(player =>
loadRlLoadout(manager, player, envMap, defaultLoadouts)
)
const bodies = await Promise.all(bodyPromises)
const field = buildPlayfield(scene, envMap)
const players = bodies.map(value => buildRocketLoadoutGroup(scene, value))
const ball = buildBall(scene)
const ball = buildBall(scene, envMap)

return SceneManager.init({
scene,
Expand Down
9 changes: 7 additions & 2 deletions src/builders/ball/buildBall.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Scene } from "three"
import { Scene, Mesh, MeshStandardMaterial, Texture } from "three"

import { BALL } from "../../constants/gameObjectNames"
import GameFieldAssets from "../../loaders/scenes/GameFieldAssets"
import BallManager from "../../managers/models/BallManager"

export const buildBall = (scene: Scene) => {
export const buildBall = (scene: Scene, envMap: Texture) => {
const { ball } = GameFieldAssets.getAssets()
ball.scale.setScalar(105)
ball.name = BALL
ball.castShadow = true
ball.traverse( child => {
if ( (child as Mesh).isMesh ) {
((child as Mesh).material as MeshStandardMaterial).envMap = envMap
}
})
scene.add(ball)
return new BallManager(ball)
}
20 changes: 16 additions & 4 deletions src/builders/field/buildPlayfield.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,42 @@ import {
MeshPhongMaterial,
PlaneBufferGeometry,
Scene,
Texture,
MeshStandardMaterial,
} from "three"

import GameFieldAssets from "../../loaders/scenes/GameFieldAssets"
import FieldManager from "../../managers/models/FieldManager"
import { addCameras } from "./addCameras"

export const buildPlayfield = (scene: Scene) => {
export const buildPlayfield = (scene: Scene, envMap: Texture) => {
/**
* Temporary
*/
const goalPlane = new PlaneBufferGeometry(2000, 1284.5, 1, 1)
const goalPlane = new PlaneBufferGeometry(1800, 630, 1, 1)
const blueGoalMaterial = new MeshPhongMaterial({
color: "#2196f3",
side: DoubleSide,
opacity: 0.3,
transparent: true,
emissive: "#2196f3",
emissiveIntensity: 0.7
})
const orangeGoalMaterial = new MeshPhongMaterial({
color: "#ff9800",
side: DoubleSide,
opacity: 0.3,
transparent: true,
emissive: "#ff9800",
emissiveIntensity: 0.7
})
const blueGoal = new Mesh(goalPlane, blueGoalMaterial)
blueGoal.position.z = -5120
blueGoal.position.y = 315
scene.add(blueGoal)
const orangeGoal = new Mesh(goalPlane, orangeGoalMaterial)
orangeGoal.position.z = 5120
orangeGoal.position.y = 315
orangeGoal.rotation.y = Math.PI
scene.add(orangeGoal)
/**
Expand All @@ -40,8 +48,12 @@ export const buildPlayfield = (scene: Scene) => {

const { field } = GameFieldAssets.getAssets()
field.scale.setScalar(400)

field.children.forEach(child => (child.receiveShadow = true))
field.traverse(child => {
child.receiveShadow = true;
if ((child as Mesh).isMesh) {
((child as Mesh).material as MeshStandardMaterial).envMap = envMap
}
})
field.receiveShadow = true
scene.add(field)

Expand Down
26 changes: 26 additions & 0 deletions src/builders/scene/addEnvironment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Scene, WebGLRenderer, WebGLRenderTargetCube } from "three"

import { PMREMGenerator } from "three/examples/jsm/pmrem/PMREMGenerator"
import { PMREMCubeUVPacker } from "three/examples/jsm/pmrem/PMREMCubeUVPacker"
import GameFieldAssets from "../../loaders/scenes/GameFieldAssets"

export const addEnvironment = (scene: Scene, renderer: WebGLRenderer) => {
const { environment } = GameFieldAssets.getAssets()

const cubeMap = new WebGLRenderTargetCube(2048, 2048).fromEquirectangularTexture(renderer, environment)

const pmremGenerator = new PMREMGenerator( cubeMap.texture );
pmremGenerator.update( renderer );

const pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );

// @ts-ignore
scene.background = cubeMap;

pmremGenerator.dispose();
pmremCubeUVPacker.dispose();

const envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
return envMap
}
10 changes: 1 addition & 9 deletions src/builders/scene/addLighting.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import { AmbientLight, DirectionalLight, HemisphereLight, Scene } from "three"
import { DirectionalLight, Scene } from "three"

export const addLighting = (scene: Scene) => {
// Ambient light provides uniform lighting to all objects in the scene
const ambientLight = new AmbientLight(0xffffff, 0.2)
scene.add(ambientLight)

// Hemisphere light gives the cars their shine and color
const hemisphereLight = new HemisphereLight(0xffffbb, 0xffffff, 0.5)
scene.add(hemisphereLight)

// The directional light is purely responsible for casting shadows
const dirLight = new DirectionalLight(0xffffff, 1.5)
dirLight.color.setHSL(0.1, 1, 0.95)
Expand Down
24 changes: 24 additions & 0 deletions src/loaders/operators/loadRGBE.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { LoadingManager, DataTexture, UnsignedByteType } from "three"
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"

export const loadRGBE = (path: string, loadingManager?: LoadingManager) => {
return new Promise(
(
resolve: (rgbeTexture: DataTexture) => void,
reject: (err: Error | ErrorEvent) => void
) => {
const rgbeLoader = new RGBELoader(loadingManager)
rgbeLoader.setDataType( UnsignedByteType )
rgbeLoader.load(
path,
(rgbeTexture: DataTexture) => {
resolve(rgbeTexture)
},
undefined,
(error: Error | ErrorEvent) => {
reject(error)
}
)
}
)
}
12 changes: 8 additions & 4 deletions src/loaders/scenes/GameFieldAssets.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Group, LoadingManager, Object3D } from "three"
import { Group, LoadingManager, Object3D, DataTexture } from "three"

import { loadBall } from "../storage/loadBall"
import { loadField } from "../storage/loadField"
import { loadEnvironment } from "../storage/loadEnvironment"

interface AvailableAssets {
ball: Object3D
field: Group
environment: DataTexture
}

class GameFieldAssets {
Expand All @@ -20,11 +22,13 @@ class GameFieldAssets {
const lm = this.loadingManager
return Promise.all([
loadBall(lm),
loadField(lm)
]).then(([ball, field]) => {
loadField(lm),
loadEnvironment(lm)
]).then(([ball, field, environment]) => {
this.assets = {
ball,
field
field,
environment
} as AvailableAssets
})
}
Expand Down
Loading