195 lines
6.9 KiB
Swift
195 lines
6.9 KiB
Swift
import JolkEngine
|
|
import Foundation
|
|
import simd
|
|
|
|
|
|
struct Scene1: Scene
|
|
{
|
|
private var env = Environment()
|
|
|
|
private var worldMesh = RenderMesh<VertexPositionNormalColourTexcoord>.empty
|
|
private var cube = RenderMesh<VertexPositionNormalTexcoord>.empty
|
|
private var suzanne = RenderMesh<VertexPositionNormalTexcoord>.empty
|
|
private var toybox = RenderMesh<VertexPositionNormalTexcoord>.empty
|
|
private var jolkTex = Texture2D.empty, suzanneDiffuse = Texture2D.empty
|
|
|
|
private var drawEdges = false
|
|
private var world = Collision()
|
|
private var colin = Colin()
|
|
private var jolkCube = JolkCube(position: .init(0, 1, -4))
|
|
private var lightTheta: Float = 0
|
|
|
|
|
|
mutating func setup(render: inout any JolkEngine.Renderer)
|
|
{
|
|
render.clearColour = XnaColour.CornflowerBlue
|
|
|
|
env.setFog(
|
|
colour: XnaColour.CornflowerBlue,
|
|
//mode: .depth, falloff: .range(type: .linear, start: 4, end: 38))
|
|
//mode: .depth, falloff: .range(type: .linear, start: 1.25, end: 24.5))
|
|
//mode: .distance, falloff: .factor(type: .exp2, density: 0.1))
|
|
mode: .depth, falloff: .factor(type: .exp2, density: 0.0222))
|
|
|
|
env.addAmbientLight(colour: XnaColour.DarkSlateGray.lighten(by: -0.666))
|
|
env.addDirectionalLight(
|
|
direction: -Vec3f(1, -1, -1).normalised,
|
|
colour: XnaColour.BlanchedAlmond
|
|
.lighten(by: -0.02)
|
|
.mix(with: XnaColour.LightSlateGray, 0.5)
|
|
.mix(with: XnaColour.White, 0.125))
|
|
env.addPointLight(
|
|
position: Vec3f(3, 0.33, -5),
|
|
colour: XnaColour.Green.mix(with: XnaColour.Gray, 0.5),
|
|
intensity: 2)
|
|
env.addPointLight(
|
|
position: Vec3f(5.5, 0.33, -6),
|
|
colour: XnaColour.Red.mix(with: XnaColour.Gray, 0.5),
|
|
intensity: 2)
|
|
env.addPointLight(
|
|
position: Vec3f(4, 0.33, -7),
|
|
colour: XnaColour.Blue.mix(with: XnaColour.Gray, 0.5),
|
|
intensity: 2)
|
|
}
|
|
|
|
mutating func loadContent(content: inout JolkEngine.ContentManager) throws
|
|
{
|
|
try loadWorld(&content)
|
|
cube = try content.create(mesh: .init(
|
|
vertices: [
|
|
.init(position: Vec3f(-1, -1, 1), normal: .forward, texCoord: Vec2f(0, 0)),
|
|
.init(position: Vec3f( 1, -1, 1), normal: .forward, texCoord: Vec2f(1, 0)),
|
|
.init(position: Vec3f(-1, 1, 1), normal: .forward, texCoord: Vec2f(0, 1)),
|
|
.init(position: Vec3f( 1, 1, 1), normal: .forward, texCoord: Vec2f(1, 1)),
|
|
.init(position: Vec3f( 1, -1, 1), normal: .right, texCoord: Vec2f(0, 0)),
|
|
.init(position: Vec3f( 1, -1, -1), normal: .right, texCoord: Vec2f(1, 0)),
|
|
.init(position: Vec3f( 1, 1, 1), normal: .right, texCoord: Vec2f(0, 1)),
|
|
.init(position: Vec3f( 1, 1, -1), normal: .right, texCoord: Vec2f(1, 1)),
|
|
.init(position: Vec3f( 1, -1, -1), normal: .back, texCoord: Vec2f(0, 0)),
|
|
.init(position: Vec3f(-1, -1, -1), normal: .back, texCoord: Vec2f(1, 0)),
|
|
.init(position: Vec3f( 1, 1, -1), normal: .back, texCoord: Vec2f(0, 1)),
|
|
.init(position: Vec3f(-1, 1, -1), normal: .back, texCoord: Vec2f(1, 1)),
|
|
.init(position: Vec3f(-1, -1, -1), normal: .left, texCoord: Vec2f(0, 0)),
|
|
.init(position: Vec3f(-1, -1, 1), normal: .left, texCoord: Vec2f(1, 0)),
|
|
.init(position: Vec3f(-1, 1, -1), normal: .left, texCoord: Vec2f(0, 1)),
|
|
.init(position: Vec3f(-1, 1, 1), normal: .left, texCoord: Vec2f(1, 1)),
|
|
.init(position: Vec3f(-1, -1, -1), normal: .down, texCoord: Vec2f(0, 0)),
|
|
.init(position: Vec3f( 1, -1, -1), normal: .down, texCoord: Vec2f(1, 0)),
|
|
.init(position: Vec3f(-1, -1, 1), normal: .down, texCoord: Vec2f(0, 1)),
|
|
.init(position: Vec3f( 1, -1, 1), normal: .down, texCoord: Vec2f(1, 1)),
|
|
.init(position: Vec3f(-1, 1, 1), normal: .up, texCoord: Vec2f(0, 0)),
|
|
.init(position: Vec3f( 1, 1, 1), normal: .up, texCoord: Vec2f(1, 0)),
|
|
.init(position: Vec3f(-1, 1, -1), normal: .up, texCoord: Vec2f(0, 1)),
|
|
.init(position: Vec3f( 1, 1, -1), normal: .up, texCoord: Vec2f(1, 1))
|
|
],
|
|
indices: [
|
|
0, 1, 2, 2, 1, 3,
|
|
4, 5, 6, 6, 5, 7,
|
|
8, 9, 10, 10, 9, 11,
|
|
12, 13, 14, 14, 13, 15,
|
|
16, 17, 18, 18, 17, 19,
|
|
20, 21, 22, 22, 21, 23 ]))
|
|
suzanne = try content.load("suzanne.g3db")
|
|
toybox = try content.load("toybox.g3db")
|
|
|
|
|
|
let linearMipped = Texture2DParameters(
|
|
minFilter: .linear, magFilter: .linear,
|
|
wrapMode: .repeating,
|
|
mipMode: .linear)
|
|
let linearClamp = Texture2DParameters(
|
|
minFilter: .linear, magFilter: .linear,
|
|
wrapMode: .clampEdge)
|
|
|
|
jolkTex = try content.load("jolkmeup.jpg", params: linearClamp)
|
|
suzanneDiffuse = try content.load("suzanne_diffuse.png", params: linearMipped)
|
|
}
|
|
|
|
private mutating func loadWorld(_ content: inout ContentManager) throws
|
|
{
|
|
let name = "World.obj"
|
|
let obj = try ObjReader.read(url: try content.getResource(name))
|
|
let mesh: Mesh = try ObjLoader.read(model: obj, content: &content)
|
|
worldMesh = try content.create(mesh: mesh)
|
|
|
|
if let collision = obj.objects["Collision3D"]
|
|
{
|
|
world.build(obj: obj, collision: collision)
|
|
}
|
|
}
|
|
|
|
mutating func update(deltaTime: Float)
|
|
{
|
|
colin.update(deltaTime: deltaTime, world: world)
|
|
jolkCube.update(deltaTime: deltaTime, world: world)
|
|
|
|
// Update point lights
|
|
lightTheta += deltaTime
|
|
var theta = Vec3f(repeating: lightTheta) * Vec3f(0.12, 0.011, 0.056) * 6
|
|
var i = env.lights.startIndex
|
|
while i != env.lights.endIndex
|
|
{
|
|
if case .point(let colour, _, _) = env.lights[i]
|
|
{
|
|
env.lights[i] = .point(
|
|
colour: colour,
|
|
position: Vec3f(
|
|
4 + 6 * cos(theta[0]),
|
|
0.33 + 0.33 * sin(theta[1]),
|
|
-6 + 3 * sin(theta[0] * 2)),
|
|
intensity: 3.1 + 1.53 * cos(theta[2]))
|
|
|
|
let spacing = 0.5 * Float.pi * (2 / 3.0)
|
|
theta += spacing * Vec3f(1, 0.98, 0.5566)
|
|
}
|
|
i = env.lights.index(after: i)
|
|
}
|
|
|
|
if Input.instance.keyboard.keyPressed(.c) { drawEdges = !drawEdges }
|
|
}
|
|
|
|
func draw(render: inout Renderer, deltaTime: Float, aspectRatio aspect: Float)
|
|
{
|
|
// Setup camera
|
|
render.setProjection(matrix:
|
|
.perspective(fovY: Float.rad(fromDeg: colin.fov), aspect: aspect, zNear: 0.1, zFar: 100))
|
|
render.setView(matrix: colin.transform)
|
|
|
|
// Draw world
|
|
for s in worldMesh.subMeshes
|
|
{
|
|
//render.setMaterial(Material(
|
|
// specular: XnaColour.BlanchedAlmond.mix(with: .black, 0.12),
|
|
// texture: texture.id))
|
|
if s.material != -1
|
|
{
|
|
render.setMaterial(worldMesh.materials[s.material])
|
|
}
|
|
else
|
|
{
|
|
render.setMaterial(.init())
|
|
}
|
|
render.draw(mesh: worldMesh, subMesh: s, environment: env)
|
|
}
|
|
|
|
// Draw jolked up shit
|
|
render.setMaterial(Material(
|
|
specular: XnaColour.Gray,
|
|
gloss: 20.0,
|
|
texture: jolkTex.id))
|
|
render.draw(mesh: cube, model: jolkCube.transform, environment: env)
|
|
|
|
render.setMaterial(Material(texture: suzanneDiffuse.id))
|
|
render.draw(mesh: suzanne, model: .translate(.up + Vec3f(3.0, 0.0, -3.5) * 2.5), environment: env)
|
|
|
|
render.draw(mesh: toybox,
|
|
model: .translate(Vec3f(6.0, 0.667, -3.5) * Vec3f(2.5, 1, 2.5))
|
|
* .rotate(y: lightTheta * 0.5) * .scale(scalar: 0.25), environment: env)
|
|
|
|
if drawEdges
|
|
{
|
|
world.draw(render, position: colin.position)
|
|
}
|
|
}
|
|
}
|