Skip to content

Commit

Permalink
Merge pull request #21 from arhik/splatting
Browse files Browse the repository at this point in the history
merging Splatting branch
  • Loading branch information
arhik authored Mar 2, 2024
2 parents e7b0528 + e2b52ed commit 4002f5c
Show file tree
Hide file tree
Showing 12 changed files with 684 additions and 113 deletions.
5 changes: 2 additions & 3 deletions examples/glyphTest.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using FreeType
using WGPUCore: CStruct, cStruct, ptr, concrete

using GeometryBasics: Vec2
using WGPUgfx

rootType(::Type{Ref{T}}) where T = T

Expand Down Expand Up @@ -29,7 +28,7 @@ function loadFace(filename::String, ftlib=ftLib[])
return face[]
end

face = loadFace(joinpath(@__DIR__, "..", "assets", "JuliaMono", "JuliaMono-Light.ttf"))
face = loadFace(joinpath(pkgdir(WGPUgfx), "assets", "JuliaMono", "JuliaMono-Light.ttf"))

FT_Set_Pixel_Sizes(face, 1.0, 1.0)

Expand Down
53 changes: 53 additions & 0 deletions examples/quadSplat.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Revise
using Tracy
using WGPUgfx
using WGPUCore
using WGPUCanvas
using GLFW
using GLFW: WindowShouldClose, PollEvents, DestroyWindow
using LinearAlgebra
using Rotations
using StaticArrays
using WGPUNative
using Images

WGPUCore.SetLogLevel(WGPUCore.WGPULogLevel_Off)


scene = Scene()
renderer = getRenderer(scene)

pc = defaultQSplat(1)

# scene.cameraSystem = CameraSystem([camera1, camera2])

addObject!(renderer, pc, scene.cameraSystem[1])

# attachEventSystem(renderer)

function runApp(renderer)
init(renderer)
render(renderer)
deinit(renderer)
end

mainApp = () -> begin
try
count = 0
while !WindowShouldClose(scene.canvas.windowRef[])
@tracepoint "runAppLoop" runApp(renderer)
PollEvents()
end
finally
WGPUCore.destroyWindow(scene.canvas)
end
end

if abspath(PROGRAM_FILE)==@__FILE__
mainApp()
else
mainApp()
end



35 changes: 32 additions & 3 deletions examples/splat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,17 @@ WGPUCore.SetLogLevel(WGPUCore.WGPULogLevel_Off)
scene = Scene()
renderer = getRenderer(scene)

# pc = defaultGSplat(joinpath(pkgdir(WGPUgfx), "assets", "bonsai", "bonsai_30000.ply"))
pc = defaultGSplat(joinpath(ENV["HOME"], "Downloads", "train", "train_30000.ply"))
# pc = defaultGSplat(joinpath(ENV["HOME"], "Downloads", "bonsai", "bonsai_30000.ply"))
getHomePath() = begin
if Sys.isunix()
return ENV["HOME"]
elseif Sys.iswindows()
return ENV["HOMEPATH"]
end
end

# pc = defaultGSplat(joinpath(getHomePath(), "Downloads", "bonsai", "bonsai_30000.ply"))
pc = defaultGSplat(joinpath(getHomePath(), "Downloads", "train", "train_30000.ply"))
# pc = defaultGSplat(joinpath(getHomePath(), "Downloads", "bicycle", "bicycle_30000.ply"))

axis = defaultAxis()

Expand All @@ -33,14 +41,35 @@ function runApp(renderer)
deinit(renderer)
end


mainApp = () -> begin
try
global renderer
if !GLFW.is_initialized()
scene.canvas = WGPUCore.getCanvas(:GLFW)
renderer = getRenderer(scene)
end
attachEventSystem(renderer)
splatDataCopy = WGPUCore.readBuffer(scene.gpuDevice, pc.splatBuffer, 0, pc.splatBuffer.size)
gsplatInCopy = reinterpret(WGSLTypes.GSplatIn, splatDataCopy)
sortIdxs = sortperm(gsplatInCopy, by=x->x.pos[3])
gsplatInSorted = gsplatInCopy[sortIdxs]
storageData = reinterpret(UInt8, gsplatInSorted)
WGPUCore.writeBuffer(
scene.gpuDevice.queue,
pc.splatBuffer,
storageData[:],
)
while !WindowShouldClose(scene.canvas.windowRef[])
runApp(renderer)
PollEvents()
end
catch e
@info e
finally
detachEventSystem(renderer)
WGPUCore.destroyWindow(scene.canvas)
GLFW.Terminate()
end
end

Expand Down
2 changes: 2 additions & 0 deletions src/camerasystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ function getShaderCode(camSys::CameraSystem;binding=1)
shaderSource = quote
struct CameraUniform
eye::Vec3{Float32}
aspectRatio::Float32
lookAt::Vec3{Float32}
fov::Float32
viewMatrix::Mat4{Float32}
projMatrix::Mat4{Float32}
Expand Down
60 changes: 51 additions & 9 deletions src/events.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ using Rotations
using StaticArrays
using LinearAlgebra

export attachEventSystem
export attachEventSystem, detachEventSystem

mutable struct MouseState
leftClick
Expand All @@ -16,7 +16,7 @@ mutable struct MouseState
speed
end

mouseState = MouseState(false, false, false, (0, 0), (0.01, 0.01))
mouseState = MouseState(false, false, false, (0, 0), (0.02, 0.02))


istruthy(::Val{GLFW.PRESS}) = true
Expand Down Expand Up @@ -54,9 +54,13 @@ end
function attachScrollCallback(scene, camera::Camera)
WGPUCanvas.setScrollCallback(
scene.canvas,
#(_, xoff, yoff) -> begin
# # @info "MouseScroll" xoff, yoff
# camera.scale = camera.scale .+ yoff.*maximum(mouseState.speed)
#end
(_, xoff, yoff) -> begin
camera.eye += (camera.eye - camera.lookat)*yoff.*maximum(mouseState.speed)
camera.lookat += (camera.eye-camera.lookat)*yoff.*maximum(mouseState.speed)
camera.eye += (camera.eye - camera.lookAt)*yoff.*maximum(mouseState.speed)
camera.lookAt += (camera.eye - camera.lookAt)*yoff.*maximum(mouseState.speed)
end
)
end
Expand All @@ -70,14 +74,14 @@ function attachCursorPosCallback(scene, camera::Camera)
if mouseState.leftClick
delta = -1.0.*(mouseState.prevPosition .- (y, x)).*mouseState.speed
rot = RotXY(delta...)
#camera.eye = rot*camera.eye
mat = MMatrix{4, 4, Float32}(I)
mat[1:3, 1:3] = rot
updateViewTransform!(camera, camera.uniformData.viewMatrix*mat)
camera.eye = rot*camera.eye
#mat = MMatrix{4, 4, Float32}(I)
#mat[1:3, 1:3] = rot
#updateViewTransform!(camera, camera.uniformData.viewMatrix*mat)
mouseState.prevPosition = (y, x)
elseif mouseState.rightClick
delta = -1.0.*(mouseState.prevPosition .- (y, x)).*mouseState.speed
#camera.lookat += [delta..., 0]
#camera.lookAt += [delta..., 0]
#camera.eye += [delta..., 0]
#mat = MMatrix{4, 4, Float32}(I)
#mat[1:3, 3] .= [delta..., 0]
Expand All @@ -96,11 +100,49 @@ function attachCursorPosCallback(scene, camera::Camera)
end


function attachKeyCallback(scene, camera::Camera)
WGPUCanvas.setKeyCallback(
scene.canvas,
(_, key, scancode, action, mods) -> begin
name = GLFW.GetKeyName(key, scancode)
if name == "a" && action == GLFW.PRESS
attachMouseButtonCallback(scene, camera)
attachScrollCallback(scene, camera)
attachCursorPosCallback(scene, camera)
elseif name == "d" && action == GLFW.PRESS
detachMouseButtonCallback(scene, camera)
detachScrollCallback(scene, camera)
detachCursorPosCallback(scene, camera)
end
end
)
end

function detachMouseButtonCallback(scene, camera)
WGPUCanvas.setMouseButtonCallback(scene.canvas, nothing)
end

function detachScrollCallback(scene, camera)
WGPUCanvas.setScrollCallback(scene.canvas, nothing)
end

function detachCursorPosCallback(scene, camera)
WGPUCanvas.setCursorPosCallback(scene.canvas, nothing)
end

function attachEventSystem(renderer)
scene = renderer.scene
camera = scene.camera
attachMouseButtonCallback(scene, camera)
attachScrollCallback(scene, camera)
attachCursorPosCallback(scene, camera)
attachKeyCallback(scene, camera)
end

function detachEventSystem(renderer)
scene = renderer.scene
camera = scene.camera
detachMouseButtonCallback(scene, camera)
detachScrollCallback(scene, camera)
detachCursorPosCallback(scene, camera)
end
56 changes: 38 additions & 18 deletions src/primitives/camera.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ export defaultCamera, Camera, lookAtLeftHanded, perspectiveMatrix, orthographicM
coordinateTransform = [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1] .|> Float32
invCoordinateTransform = inv(coordinateTransform)

@enum WGPUProjectionType ORTHO=0 PERSPECTIVE=1 # TODO add others projection types

mutable struct Camera
gpuDevice
eye
lookat
lookAt
up
scale
fov
Expand All @@ -28,6 +30,7 @@ mutable struct Camera
uniformData
uniformBuffer
id
projectionType
end

function prepareObject(gpuDevice, camera::Camera)
Expand All @@ -43,7 +46,11 @@ function prepareObject(gpuDevice, camera::Camera)
setfield!(camera, :uniformData, uniformData)
setfield!(camera, :uniformBuffer, uniformBuffer)
setfield!(camera, :gpuDevice, gpuDevice)
# TODO could be general design
# TODO setting parameters that are common in CPU and GPU structures automatically
camera.fov = camera.fov
camera.lookAt = camera.lookAt
camera.aspectRatio = camera.aspectRatio
return camera
end

Expand All @@ -57,7 +64,12 @@ end

function computeTransform(camera::Camera)
viewMatrix = lookAtLeftHanded(camera) scaleTransform(camera.scale .|> Float32)
projectionMatrix = perspectiveMatrix(camera)
# TODO should use dispatch instead
if camera.projectionType == ORTHO
projectionMatrix = orthographicMatrix(camera)
elseif camera.projectionType == PERSPECTIVE
projectionMatrix = perspectiveMatrix(camera)
end
return (viewMatrix.linear, projectionMatrix.linear)
end

Expand All @@ -72,19 +84,24 @@ function computeUniformData(camera::Camera)
end


function defaultCamera(;id=0)
eye = [0.0, 0.0, 4.0] .|> Float32
lookat = [0, 0, 0] .|> Float32
up = [0, 1, 0] .|> Float32
scale = [1, 1, 1] .|> Float32
fov = (75/180)*pi |> Float32
aspectRatio = 1.0 |> Float32
nearPlane = 0.1 |> Float32
farPlane = 100.0 |> Float32
function defaultCamera(;
id=0,
eye = [0.0, 0.0, 3.0] .|> Float32,
lookAt = [0, 0, 0] .|> Float32,
up = [0, 1, 0] .|> Float32,
scale = [1, 1, 1] .|> Float32,
fov = (45/180)*pi |> Float32,
aspectRatio = 1.0 |> Float32,
nearPlane = 1 |> Float32,
farPlane = 1000.0 |> Float32,
projectionType::Union{Symbol, WGPUProjectionType} = :PERSPECTIVE
)
projectionType = eval(projectionType) # Handles both symbol and direct Enum
@assert projectionType in instances(WGPUProjectionType) "This projection Type is not defined"
return Camera(
nothing,
eye,
lookat,
lookAt,
up,
scale,
fov,
Expand All @@ -93,7 +110,8 @@ function defaultCamera(;id=0)
farPlane,
nothing,
nothing,
id
id,
projectionType
)
end

Expand Down Expand Up @@ -241,9 +259,9 @@ transform([upperCoords(bb1)..., 0, 0])

function lookAtLeftHanded(camera::Camera)
eye = camera.eye
lookat = camera.lookat
up = camera.up
w = -(lookat .- eye) |> normalize
lookAt = camera.lookAt
up = -camera.up
w = -(lookAt .- eye) |> normalize
u = cross(up, w) |> normalize
v = cross(w, u)
m = MMatrix{4, 4, Float32}(I)
Expand All @@ -258,7 +276,7 @@ function perspectiveMatrix(camera::Camera)
ar = camera.aspectRatio
n = camera.nearPlane
f = camera.farPlane
t = n*tan(fov/2)
t = abs(n)*tan(fov/2)
b = -t
r = ar*t
l = -r
Expand All @@ -273,7 +291,7 @@ function perspectiveMatrix(near::Float32, far::Float32, l::Float32, r::Float32,
yS = 2*n/(t-b) # (t-b) is height
xR = (r+l)/(r-l)
yR = (t+b)/(t-b)
zR = -(f)/(f-n)
zR = -(f+n)/(f-n)
oR = -2*f*n/(f-n)
pmat = coordinateTransform * [
xS 0 xR 0 ;
Expand Down Expand Up @@ -346,6 +364,8 @@ function getShaderCode(camera::Camera; binding=CAMERA_BINDING_START)
shaderSource = quote
struct $cameraUniform
eye::Vec3{Float32}
aspectRatio::Float32
lookAt::Vec3{Float32}
fov::Float32
viewMatrix::Mat4{Float32}
projMatrix::Mat4{Float32}
Expand Down
4 changes: 2 additions & 2 deletions src/primitives/lighting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ transform([upperCoords(bb1)..., 0, 0])

function lookAtRightHanded(lighting::Lighting)
eye = lighting.eye
lookat = lighting.lookat
lookAt = lighting.lookAt
up = lighting.up
w = -(eye .- lookat) |> normalize
w = -(eye .- lookAt) |> normalize
u = cross(up, w) |> normalize
v = cross(w, u)
m = Matrix{Float32}(I, (4, 4))
Expand Down
2 changes: 1 addition & 1 deletion src/scene.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mutable struct Scene
objects # ::Union{WorldObject, ObjectGroup}
function Scene()
canvas = WGPUCore.getCanvas(:GLFW)
gpuDevice = WGPUCore.getDefaultDevice();
gpuDevice = WGPUCore.getDefaultDevice(canvas);
camera = defaultCamera()
light = defaultLighting()
cameraSystem = CameraSystem(Camera[])
Expand Down
Loading

0 comments on commit 4002f5c

Please sign in to comment.