Skip to content

Commit

Permalink
client: use 3D camera for rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffomatic committed Dec 21, 2020
1 parent 784922e commit f99cd10
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 24 deletions.
57 changes: 47 additions & 10 deletions src/Client.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { vec2 } from 'gl-matrix'
import { mat2d } from 'gl-matrix'

import { Renderer2d } from './renderer/Renderer2d'
import { vec3 } from 'gl-matrix'
import { quat } from 'gl-matrix'

import { Camera2d } from '~/camera/Camera2d'
import { Camera3d } from '~/camera/Camera3d'
import {
MAX_PREDICTED_FRAMES,
SIMULATION_PERIOD_S,
Expand All @@ -19,12 +20,14 @@ import { ClientMessage, ClientMessageType } from '~/network/ClientMessage'
import { IServerConnection } from '~/network/ServerConnection'
import { ServerMessage, ServerMessageType } from '~/network/ServerMessage'
import { ParticleEmitter } from '~/particles/ParticleEmitter'
import { Renderer2d } from '~/renderer/Renderer2d'
import { Primitive2d, Renderable2d, TextAlign } from '~/renderer/Renderer2d'
import { Renderer3d } from '~/renderer/Renderer3d'
import { simulate } from '~/simulate'
import * as systems from '~/systems'
import { CursorMode } from '~/systems/client/playerInput'
import * as terrain from '~/terrain'
import * as math from '~/util/math'
import { RunningAverage } from '~/util/RunningAverage'
import * as time from '~/util/time'

Expand All @@ -44,7 +47,8 @@ export class Client {
simulationFrame: number
waitingForServer: boolean

camera: Camera2d
camera2d: Camera2d
camera: Camera3d
debugDraw2dRenderables: Renderable2d[]
emitters: ParticleEmitter[]
emitterHistory: Set<string>
Expand Down Expand Up @@ -95,11 +99,12 @@ export class Client {
this.simulationFrame = 0
this.waitingForServer = false

this.camera = new Camera2d(
this.camera2d = new Camera2d(
vec2.fromValues(config.canvas3d.width, config.canvas3d.height),
vec2.create(),
vec2.create(),
)
this.camera = new Camera3d()
this.emitters = []
this.emitterHistory = new Set()
this.debugDraw2dRenderables = []
Expand Down Expand Up @@ -147,7 +152,7 @@ export class Client {
}

setViewportDimensions(d: vec2): void {
this.camera.setViewportDimensions(d)
this.camera2d.setViewportDimensions(d)
this.renderer3d.setViewportDimensions(d)
this.renderer2d.setViewportDimensions(d)
}
Expand Down Expand Up @@ -190,8 +195,8 @@ export class Client {
const bulletModel = getModel('bullet')
this.renderer3d.loadModel('bullet', bulletModel)

this.camera.minWorldPos = this.terrainLayer.minWorldPos()
this.camera.worldDimensions = this.terrainLayer.dimensions()
this.camera2d.minWorldPos = this.terrainLayer.minWorldPos()
this.camera2d.worldDimensions = this.terrainLayer.dimensions()
}

setState(s: GameState): void {
Expand Down Expand Up @@ -307,9 +312,41 @@ export class Client {
const playerId = this.entityManager.getPlayerId(this.playerNumber)
if (playerId) {
const transform = this.entityManager.transforms.get(playerId)!
this.camera.setPosition(transform.position)
this.camera2d.setPosition(transform.position)
this.camera2d.update(dt)

// Position the 3D camera at a fixed offset from the player, and
// point the camera directly at the player.
const offset = vec3.fromValues(0, 7, 4)
this.camera.setPos(
vec3.add(
vec3.create(),
vec3.fromValues(
transform.position[0],
0,
transform.position[1],
),
offset,
),
)
this.camera.setOrientation(
quat.fromEuler(
quat.create(),
// We want the value of b, which is a negative-value downward
// rotation around the x-axis.
// c ------------------
// | \ b
// | a \
// | \
// | \
// | \
// ----------- p ------
math.r2d(Math.atan2(offset[2], offset[1]) - Math.PI / 2),
0,
0,
),
)
}
this.camera.update(dt)

this.keyboard?.update()
this.mouse?.update()
Expand Down Expand Up @@ -337,7 +374,7 @@ export class Client {

this.renderer3d.clear('magenta')

this.renderer3d.setCameraWorldPos(this.camera.getPosition())
this.renderer3d.setWvTransform(this.camera.getWvTransform())
this.renderer3d.drawModel('terrain', vec2.create(), 0)

// GRID DEBUG
Expand Down
38 changes: 38 additions & 0 deletions src/camera/Camera3d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { mat4 } from 'gl-matrix'
import { quat, vec3 } from 'gl-matrix'

import { Immutable } from '~/types/immutable'

export class Camera3d {
private pos: vec3
private orientation: quat

constructor() {
this.pos = vec3.create()
this.orientation = quat.create()
}

getPos(): Immutable<vec3> {
return this.pos
}

getOrientation(): Immutable<quat> {
return this.orientation
}

getWvTransform(): mat4 {
const res = mat4.create()
return mat4.invert(
res,
mat4.fromRotationTranslation(res, this.orientation, this.pos),
)
}

setPos(v: Immutable<vec3>): void {
this.pos = vec3.clone(v)
}

setOrientation(q: Immutable<quat>): void {
this.orientation = quat.clone(q)
}
}
14 changes: 1 addition & 13 deletions src/renderer/Renderer3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ void main() {
export class Renderer3d {
private canvas: HTMLCanvasElement
private ctx: WebGL2RenderingContext
private cameraWorldPos: vec3
private program: WebGLProgram

private vaos: {
Expand All @@ -48,7 +47,6 @@ export class Renderer3d {
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas
this.ctx = canvas.getContext('webgl2')!
this.cameraWorldPos = vec3.create()

const vertexShader = this.ctx.createShader(gl.VERTEX_SHADER)!
this.ctx.shaderSource(vertexShader, vertexShaderSrc)
Expand Down Expand Up @@ -100,17 +98,7 @@ export class Renderer3d {
)
}

setCameraWorldPos(p: vec2): void {
this.cameraWorldPos = vec3.fromValues(p[0], 7.0, p[1] + 4)

// Move camera in world space
const v2w = mat4.fromRotationTranslation(
mat4.create(),
quat.fromEuler(quat.create(), -60, 0, 0),
this.cameraWorldPos,
)
const w2v = mat4.invert(mat4.create(), v2w)

setWvTransform(w2v: mat4): void {
this.ctx.uniformMatrix4fv(
this.ctx.getUniformLocation(this.program, 'uXform'),
false,
Expand Down
2 changes: 1 addition & 1 deletion src/systems/client/playerInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const handleAttackInput = (client: Client, frame: number): void => {
frame,
playerNumber: client.playerNumber,
type: ClientMessageType.TANK_AIM,
targetPos: client.camera.viewToWorldspace(mousePos),
targetPos: client.camera2d.viewToWorldspace(mousePos),
firing: client.mouse.isDown(MouseButton.LEFT),
})
}
Expand Down
8 changes: 8 additions & 0 deletions src/types/gl-matrix/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@ declare module 'gl-matrix' {
b: Immutable<vec2>,
): vec2
}

export namespace vec3 {
export function clone(a: Immutable<vec3>): vec3
}

export namespace vec4 {
export function clone(a: Immutable<vec4>): vec4
}
}
7 changes: 7 additions & 0 deletions src/util/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,10 @@ export const transformCircle = (
radius: vec2.length(vec2.sub(edge, edge, center)),
}
}

/**
* Convert radians to degrees
*/
export function r2d(radians: number): number {
return (radians * 180) / Math.PI
}

0 comments on commit f99cd10

Please sign in to comment.