Compare commits

..

No commits in common. "294e1dd919a5a61ac2cc0a2ca35857873d064c14" and "28f0d737b1c7e1b893ed7e3e336c6b94741e4ea4" have entirely different histories.

4 changed files with 126 additions and 248 deletions

View file

@ -1,5 +1,7 @@
package format package format
import "core:strings"
RSW_Parse_Error :: enum { RSW_Parse_Error :: enum {
None, None,
UnexpectedEOF, UnexpectedEOF,

View file

@ -1,6 +1,5 @@
package format package format
import "core:math"
import "core:strings" import "core:strings"
import "core:fmt" import "core:fmt"
@ -153,7 +152,7 @@ parse_rsm :: proc(data: []u8) -> (RSM_Model, RSM_Parse_Error) {
count, ok = read_u32(&r); if !ok { return model, .UnexpectedEOF } count, ok = read_u32(&r); if !ok { return model, .UnexpectedEOF }
for _ in 0..<int(count) { for _ in 0..<int(count) {
name, ok = read_model_string(&r, model.version, 40); if !ok { return model, .UnexpectedEOF } name, ok = read_model_string(&r, model.version, 40); if !ok { return model, .UnexpectedEOF }
append(&node.texture_names, normalize_path(name)) append(&node.texture_names, strings.to_lower(name))
} }
} }
@ -171,10 +170,6 @@ parse_rsm :: proc(data: []u8) -> (RSM_Model, RSM_Parse_Error) {
if version_below(model.version, 2, 2) { if version_below(model.version, 2, 2) {
node.rotation_angle, ok = read_f32(&r); if !ok { return model, .UnexpectedEOF } node.rotation_angle, ok = read_f32(&r); if !ok { return model, .UnexpectedEOF }
node.rotation_axis, ok = read_vec3(&r); if !ok { return model, .UnexpectedEOF } node.rotation_axis, ok = read_vec3(&r); if !ok { return model, .UnexpectedEOF }
node.rotation_axis = { node.rotation_axis[0], node.rotation_axis[1], node.rotation_axis[2] }
// node.rotation_axis[0] = math.abs(node.rotation_axis[0])
// node.rotation_axis[2] = math.abs(node.rotation_axis[2])
// node.rotation_axis[1] = math.abs(node.rotation_axis[1])
node.scale, ok = read_vec3(&r); if !ok { return model, .UnexpectedEOF } node.scale, ok = read_vec3(&r); if !ok { return model, .UnexpectedEOF }
if node.rotation_angle == 0 { if node.rotation_angle == 0 {

View file

@ -75,27 +75,13 @@ loadTexture :: proc(path: string, textures: ^[dynamic]TextureHolder) -> int {
return index return index
} }
fileMap :: proc(path: string, output: ^map[string]string) {
f, _ := os.open(path)
entries, ok := os.read_dir(f, 0, context.allocator)
for entry in entries {
path, _ := filepath.join({path, entry.name})
if entry.type == .Directory {
fileMap(path, output)
}
else {
output[format.normalize_path(entry.fullpath)] = entry.fullpath
}
}
}
uploadTextures :: proc(device: ^sdl.GPUDevice, textures: ^[dynamic]TextureHolder) { uploadTextures :: proc(device: ^sdl.GPUDevice, textures: ^[dynamic]TextureHolder) {
setup_cmd := sdl.AcquireGPUCommandBuffer(device) setup_cmd := sdl.AcquireGPUCommandBuffer(device)
if setup_cmd == nil { if setup_cmd == nil {
fmt.println("AcquireGPUCommandBuffer failed:", sdl.GetError()) fmt.println("AcquireGPUCommandBuffer failed:", sdl.GetError())
return return
} }
// fmt.println("copying textures to transfer buffer") fmt.println("copying textures to transfer buffer")
for &texture in textures { for &texture in textures {
texture.texture = sdl.CreateGPUTexture(device, sdl.GPUTextureCreateInfo{ texture.texture = sdl.CreateGPUTexture(device, sdl.GPUTextureCreateInfo{
format = .R8G8B8A8_UNORM, format = .R8G8B8A8_UNORM,
@ -124,8 +110,8 @@ uploadTextures :: proc(device: ^sdl.GPUDevice, textures: ^[dynamic]TextureHolder
return return
} }
for &texture in textures { for &texture in textures {
// fmt.println("transferring textures") fmt.println("transferring textures")
// fmt.println("tex ptr:", texture, "w/h:", texture.w, texture.h) fmt.println("tex ptr:", texture, "w/h:", texture.w, texture.h)
sdl.UploadToGPUTexture(cp, sdl.UploadToGPUTexture(cp,
{ {
transfer_buffer = texture.transferBuffer, transfer_buffer = texture.transferBuffer,
@ -137,7 +123,7 @@ uploadTextures :: proc(device: ^sdl.GPUDevice, textures: ^[dynamic]TextureHolder
false, false,
) )
sdl.ReleaseGPUTransferBuffer(device, texture.transferBuffer) sdl.ReleaseGPUTransferBuffer(device, texture.transferBuffer)
// fmt.println("transferred textures") fmt.println("transferred textures")
} }
sdl.EndGPUCopyPass(cp) sdl.EndGPUCopyPass(cp)
@ -149,180 +135,102 @@ uploadTextures :: proc(device: ^sdl.GPUDevice, textures: ^[dynamic]TextureHolder
} }
loadGndModel :: proc(device: ^sdl.GPUDevice, model: ^format.GND_Data, vertices: ^[dynamic]shared.Vertex, indices: ^[dynamic]u32, nodes: ^[dynamic]GndNode, textures: ^[dynamic]TextureHolder, files: ^map[string]string) -> (vbuf: ^sdl.GPUBuffer, ibuf: ^sdl.GPUBuffer) { loadGndModel :: proc(device: ^sdl.GPUDevice, model: ^format.GND_Data, vertices: ^[dynamic]shared.Vertex, indices: ^[dynamic]u32, nodes: ^[dynamic]GndNode, textures: ^[dynamic]TextureHolder) -> (vbuf: ^sdl.GPUBuffer, ibuf: ^sdl.GPUBuffer) {
clear(vertices) clear(vertices)
clear(indices) clear(indices)
clear(nodes) clear(nodes)
// fmt.println("version ", model.info.version) fmt.println("version ", model.info.version)
textureMap : [dynamic]int textureMap : [dynamic]int
defer delete(textureMap) defer delete(textureMap)
// fmt.printfln("loading model texture %v", model.textures) fmt.printfln("loading model texture %v", model.textures)
for textureName in model.textures { for textureName in model.textures {
textureName, _ := strings.replace_all(textureName, "\\", "/") textureName, _ := strings.replace_all(textureName, "\\", "/")
full_path, err := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/texture", textureName}); assert(err == nil) full_path, err := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/texture", textureName}); assert(err == nil)
full_path, err = filepath.clean(full_path); assert(err == nil) full_path, err = filepath.clean(full_path); assert(err == nil)
append(&textureMap, loadTexture(files[full_path], textures)) append(&textureMap, loadTexture(full_path, textures))
} }
width := model.info.width width := model.info.width
height := model.info.height height := model.info.height
for node_idx := 0; node_idx < len(model.tiles); node_idx+= 1 { for node_idx := 0; node_idx < len(model.tiles); node_idx+= 1 {
x := i32(node_idx) % width x := i32(node_idx) % width
y := i32(node_idx) / width y := i32(node_idx) / width
node := &model.tiles[node_idx] node := &model.tiles[node_idx]
pos := shared.Vec2{f32(x) - f32(width)/2.0, f32(y) - f32(height)/2.0} // fmt.println("h_ne", node.h_ne)
// fmt.println("h_nw", node.h_nw)
// fmt.println("h_se", node.h_se)
// fmt.println("h_sw", node.h_sw)
// fmt.println("east_surface_index", node.east_surface_index)
// fmt.println("north_surface_index", node.north_surface_index)
// fmt.println("top_surface_index", node.top_surface_index)
if node.top_surface_index != -1 && model.surfaces[node.top_surface_index].texture_index != -1 {
surface := model.surfaces[node.top_surface_index]
n := GndNode{
start = len(indices),
node = node,
texture = textureMap[surface.texture_index],
}
offset := len(vertices)
append(vertices, shared.Vertex{
pos = [3]f32{pos.x, pos.y+1,node.h_nw},
uv = {surface.u[2], surface.v[2]},
})
append(vertices, shared.Vertex{
pos = [3]f32{pos.x+1,pos.y+1,node.h_ne},
uv = {surface.u[3], surface.v[3]},
})
append(vertices, shared.Vertex{
pos = [3]f32{pos.x,pos.y,node.h_sw},
uv = {surface.u[0], surface.v[0]},
})
append(vertices, shared.Vertex{
pos =[3]f32{pos.x+1,pos.y,node.h_se},
uv = {surface.u[1], surface.v[1]},
})
append(indices, u32(offset+3))
append(indices, u32(offset+1))
append(indices, u32(offset+0))
append(indices, u32(offset+3))
append(indices, u32(offset+2))
append(indices, u32(offset+0))
n.end = len(indices)
append(nodes, n) surface := model.surfaces[0]
if node.top_surface_index != -1 {
surface = model.surfaces[node.top_surface_index]
} }
if node.east_surface_index != -1 && model.surfaces[node.east_surface_index].texture_index != -1 { fmt.println(surface.u, surface.v)
if x + 1 >= width {
continue
}
neighbour := model.tiles[y * width + x + 1]
surface := model.surfaces[node.east_surface_index]
n := GndNode{
start = len(indices),
node = node,
texture = textureMap[surface.texture_index],
}
offset := len(vertices)
append(vertices, shared.Vertex{ n := GndNode{
pos = {(pos.x+1), (pos.y), neighbour.h_nw }, start = len(indices),
uv = {surface.u[2], surface.v[2]}, node = node,
}) texture = textureMap[0],
append(vertices, shared.Vertex{
pos = {(pos.x+1),(pos.y),node.h_ne},
uv = {surface.u[3], surface.v[3]},
})
append(vertices, shared.Vertex{
pos = {(pos.x+1),(pos.y+1),neighbour.h_sw},
uv = {surface.u[1], surface.v[1]},
})
append(vertices, shared.Vertex{
pos = {(pos.x+1),(pos.y+1),node.h_se},
uv = {surface.u[0], surface.v[0]},
})
append(indices, u32(offset))
append(indices, u32(offset+2))
append(indices, u32(offset+1))
append(indices, u32(offset+1))
append(indices, u32(offset+2))
append(indices, u32(offset+3))
n.end = len(indices)
append(nodes, n)
} }
if node.north_surface_index != -1 && model.surfaces[node.north_surface_index].texture_index != -1 { if surface.texture_index != -1 {
if y + 1 >= height { n.texture = textureMap[surface.texture_index]
continue
}
neighbour := model.tiles[(y+1) * width + x]
surface := model.surfaces[node.north_surface_index]
n := GndNode{
start = len(indices),
node = node,
texture = textureMap[surface.texture_index],
}
offset := len(vertices)
append(vertices, shared.Vertex{
pos = {pos.x, pos.y+1,node.h_nw },
uv = {surface.u[2], surface.v[2]},
})
append(vertices, shared.Vertex{
pos = {pos.x+1,pos.y+1,node.h_ne},
uv = {surface.u[3], surface.v[3]},
})
append(vertices, shared.Vertex{
pos = {pos.x,pos.y+1,neighbour.h_sw},
uv = {surface.u[1], surface.v[1]},
})
append(vertices, shared.Vertex{
pos = {pos.x+1,pos.y+1,neighbour.h_se},
uv = {surface.u[0], surface.v[0]},
})
append(indices, u32(offset))
append(indices, u32(offset+2))
append(indices, u32(offset+1))
append(indices, u32(offset+1))
append(indices, u32(offset+2))
append(indices, u32(offset+3))
n.end = len(indices)
append(nodes, n)
} }
} // fmt.println("top_surface_index", surface.u)
s := model.info.zoom
offset := len(vertices)
fmt.println(s) pos := shared.Vec2{f32(x) - f32(model.info.width)/2.0, f32(y) - f32(model.info.height)/2.0}
// node.h_ne = 0
// node.h_nw = 0
// node.h_se = 0
// node.h_sw = 0
translationMatrix := matrix[4,4]f32{ append(vertices, shared.Vertex{
s, 0, 0, 0, pos = {pos.x * model.info.zoom,-node.h_nw, -pos.y * model.info.zoom},
0, 0, -1, 0, uv = {surface.u[2], surface.v[2]},
0, s, 0, 0, })
0, 0, 0, 1, append(vertices, shared.Vertex{
} pos = {(pos.x+1)* model.info.zoom,-node.h_ne,-pos.y* model.info.zoom},
uv = {surface.u[3], surface.v[3]},
})
append(vertices, shared.Vertex{
pos = {pos.x* model.info.zoom,-node.h_sw,-(pos.y+1)* model.info.zoom},
uv = {surface.u[1], surface.v[1]},
})
append(vertices, shared.Vertex{
pos = {(pos.x+1)* model.info.zoom,-node.h_se,-(pos.y+1)* model.info.zoom},
uv = {surface.u[0], surface.v[0]},
})
append(indices, u32(offset))
append(indices, u32(offset+1))
append(indices, u32(offset+2))
for &vertex in vertices { append(indices, u32(offset+1))
vertex.pos = linalg.matrix_mul_vector(translationMatrix, [4]f32{vertex.pos.x, vertex.pos.y, vertex.pos.z, 1}).xyz append(indices, u32(offset+3))
append(indices, u32(offset+2))
n.end = len(indices)
append(nodes, n)
} }
vbuf_info := sdl.GPUBufferCreateInfo{ vbuf_info := sdl.GPUBufferCreateInfo{
@ -409,8 +317,6 @@ walk :: proc(dir: string, models: ^[dynamic]format.GND_Data) {
path, _ := filepath.join({dir, entry.name}) path, _ := filepath.join({dir, entry.name})
if entry.type == .Directory { if entry.type == .Directory {
walk(path, models) walk(path, models)
} else {
} }
if strings.contains(entry.name, ".gnd") { if strings.contains(entry.name, ".gnd") {
data, _ := os.read_entire_file(path, context.allocator) data, _ := os.read_entire_file(path, context.allocator)
@ -425,7 +331,7 @@ walk :: proc(dir: string, models: ^[dynamic]format.GND_Data) {
} }
loadRsw :: proc() -> format.RSW_Data { loadRsw :: proc() -> format.RSW_Data {
prontera := "/home/pavel/neoragnarok_backup/kro_client/data/geffen.rsw" prontera := "/home/pavel/neoragnarok_backup/kro_client/data/aldebaran.rsw"
data, _ := os.read_entire_file(prontera, context.allocator) data, _ := os.read_entire_file(prontera, context.allocator)
parsed, err := format.parse_rsw(data) parsed, err := format.parse_rsw(data)
if err != nil { if err != nil {
@ -435,7 +341,7 @@ loadRsw :: proc() -> format.RSW_Data {
return parsed return parsed
} }
loadRsmModel :: proc(device: ^sdl.GPUDevice, model: ^format.RSM_Model, modelIndex: int, nodes: ^[dynamic]RsmNode, textures: ^[dynamic]TextureHolder, vbufs: ^[dynamic]^sdl.GPUBuffer, ibufs: ^[dynamic]^sdl.GPUBuffer, transform: matrix[4,4]f32, files: ^map[string]string) { loadRsmModel :: proc(device: ^sdl.GPUDevice, model: ^format.RSM_Model, modelIndex: int, nodes: ^[dynamic]RsmNode, textures: ^[dynamic]TextureHolder, vbufs: ^[dynamic]^sdl.GPUBuffer, ibufs: ^[dynamic]^sdl.GPUBuffer, transform: matrix[4,4]f32) {
vertices: [dynamic]shared.Vertex vertices: [dynamic]shared.Vertex
indices: [dynamic]u16 indices: [dynamic]u16
@ -443,52 +349,44 @@ loadRsmModel :: proc(device: ^sdl.GPUDevice, model: ^format.RSM_Model, modelInde
ibufIndex := len(ibufs) ibufIndex := len(ibufs)
// fmt.printfln("version %v", model.version) fmt.printfln("version %v", model.version)
textureMap : [dynamic]int textureMap : [dynamic]int
defer delete(textureMap) defer delete(textureMap)
// fmt.printfln("loading model texture %v", model.texture_names[:]) fmt.printfln("loading model texture %v", model.texture_names[:])
for textureName in model.texture_names { for textureName in model.texture_names {
// fmt.println(textureName)
textureName, _ := strings.replace_all(textureName, "\\", "/") textureName, _ := strings.replace_all(textureName, "\\", "/")
full_path, err := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/texture", textureName}); assert(err == nil) full_path, err := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/texture", textureName}); assert(err == nil)
full_path, err = filepath.clean(full_path); assert(err == nil) full_path, err = filepath.clean(full_path); assert(err == nil)
append(&textureMap, loadTexture(files[full_path], textures)) append(&textureMap, loadTexture(full_path, textures))
}
nameToIndex : map[string]int
for node_idx := 0; node_idx < len(model.nodes); node_idx+=1 {
nameToIndex[model.nodes[node_idx].node_name] = node_idx
} }
for node_idx := 0; node_idx < len(model.nodes); node_idx+= 1 { for node_idx := 0; node_idx < len(model.nodes); node_idx+= 1 {
parentTransform: matrix[4,4]f32
textureOffset := (0) textureOffset := (0)
node := &model.nodes[node_idx] node := &model.nodes[node_idx]
// fmt.println("offset_matrix", node.offset_matrix) fmt.println("offset_matrix", node.offset_matrix)
// fmt.println("node.translation1", node.translation1) fmt.println("node.translation1", node.translation1)
// fmt.println("node.translation2", node.translation2) fmt.println("node.translation2", node.translation2)
// fmt.println("node.scale", node.scale) fmt.println("node.scale", node.scale)
// fmt.println("node.rotation_angle", node.rotation_angle) fmt.println("node.rotation_angle", node.rotation_angle)
// fmt.println("node.rotation_axis", node.rotation_axis) fmt.println("node.rotation_axis", node.rotation_axis)
// fmt.println("node.scale_keyframes[:]", node.scale_keyframes[:]) // fmt.println("node.scale_keyframes[:]", node.scale_keyframes[:])
// fmt.println("node.texture_names[:]", node.texture_names[:]) // fmt.println("node.texture_names[:]", node.texture_names[:])
if model.version.major >= 2 && model.version.minor > 2 { if model.version.major >= 2 && model.version.minor > 2 {
textureOffset = (len(textures)) textureOffset = (len(textures))
} }
for textureName in node.texture_names { for textureName in node.texture_names {
// fmt.printfln("loading texture %s", textureName) fmt.printfln("loading texture %s", textureName)
full_path, err := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/texture", textureName}); assert(err == nil) full_path, err := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/texture", textureName}); assert(err == nil)
full_path, err = filepath.clean(full_path); assert(err == nil) full_path, err = filepath.clean(full_path); assert(err == nil)
full_path, _ = strings.replace_all(full_path, "\\", "/") full_path, _ = strings.replace_all(full_path, "\\", "/")
append(&textureMap, loadTexture(files[full_path], textures)) append(&textureMap, loadTexture(full_path, textures))
} }
for face in node.faces { for face in node.faces {
@ -593,10 +491,6 @@ loadRsmModel :: proc(device: ^sdl.GPUDevice, model: ^format.RSM_Model, modelInde
} }
runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUGraphicsPipeline) { runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUGraphicsPipeline) {
files: map[string]string
fileMap("/home/pavel/neoragnarok_backup/kro_client/data", &files)
sampler := sdl.CreateGPUSampler(device, {}) sampler := sdl.CreateGPUSampler(device, {})
modelIndex := 0 modelIndex := 0
models: [dynamic]format.RSM_Model models: [dynamic]format.RSM_Model
@ -611,13 +505,13 @@ runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUG
for object in rsw.objects { for object in rsw.objects {
modelPath, err1 := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/model", object.model_name}); assert(err1 ==nil) modelPath, err1 := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data/model", object.model_name}); assert(err1 ==nil)
// fmt.println(modelPath) fmt.println(modelPath)
data, err := os.read_entire_file(modelPath, context.allocator) data, err := os.read_entire_file(modelPath, context.allocator)
if err != nil { if err != nil {
fmt.println(err) fmt.println(err)
panic("failed to read rsm") panic("failed to read rsm")
} }
// fmt.println(object.model_name) fmt.println(object.model_name)
parsed, err2 := format.parse_rsm(data) parsed, err2 := format.parse_rsm(data)
if err2 != nil { if err2 != nil {
@ -627,20 +521,18 @@ runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUG
modelIndex := len(models) modelIndex := len(models)
append_elem(&models, parsed) append_elem(&models, parsed)
p := object.transform.position T := linalg.matrix4_translate(object.transform.position)
T := linalg.matrix4_translate([3]f32{p.x,p.y,-p.z})
S := linalg.matrix4_scale(object.transform.scale) S := linalg.matrix4_scale(object.transform.scale)
Rx := linalg.matrix4_rotate_f32(linalg.to_radians(object.transform.rotation_deg.x), {1,0,0}) Rx := linalg.matrix4_rotate_f32(object.transform.rotation_deg[0], {1,0,0})
Ry := linalg.matrix4_rotate_f32(linalg.to_radians(object.transform.rotation_deg.y), {0,1,0}) Ry := linalg.matrix4_rotate_f32(object.transform.rotation_deg[1], {0,1,0})
Rz := linalg.matrix4_rotate_f32(linalg.to_radians(-object.transform.rotation_deg.z), {0,0,1}) Rz := linalg.matrix4_rotate_f32(object.transform.rotation_deg[2], {0,0,1})
R := Rz * Ry * Rx R := Rz * Ry * Rx
M := T * R * S M := T * R * S
loadRsmModel(device, &parsed, modelIndex, &rsmNodes, &textures, &rsmVbufs, &rsmIbufs, M, &files) loadRsmModel(device, &parsed, modelIndex, &rsmNodes, &textures, &rsmVbufs, &rsmIbufs, M)
} }
gnd, err1 := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data", rsw.ground_file}); assert(err1 ==nil) gnd, err1 := filepath.join({"/home/pavel/neoragnarok_backup/kro_client/data", rsw.ground_file}); assert(err1 ==nil)
@ -652,7 +544,7 @@ runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUG
gndIndices: [dynamic]u32 gndIndices: [dynamic]u32
gndNodes: [dynamic]GndNode gndNodes: [dynamic]GndNode
gndVbuf, gndIbuf := loadGndModel(device, &gndModel, &gndVertices, &gndIndices, &gndNodes, &textures, &files) gndVbuf, gndIbuf := loadGndModel(device, &gndModel, &gndVertices, &gndIndices, &gndNodes, &textures)
defer sdl.ReleaseGPUBuffer(device, gndIbuf) defer sdl.ReleaseGPUBuffer(device, gndIbuf)
defer sdl.ReleaseGPUBuffer(device, gndVbuf) defer sdl.ReleaseGPUBuffer(device, gndVbuf)
@ -706,18 +598,16 @@ runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUG
} }
case .MOUSE_WHEEL: case .MOUSE_WHEEL:
camera.distance = math.clamp(camera.distance - event.wheel.y * 0.7, 1.5, 80.0) camera.distance = math.clamp(camera.distance - event.wheel.y * 0.7, 1.5, 80.0)
case .KEY_DOWN: // case .KEY_DOWN:
if event.key.key == sdl.K_ESCAPE { // if event.key.key == sdl.K_ESCAPE {
running = false // running = false
} else if event.key.key == sdl.K_N { // } else if event.key.key == sdl.K_N {
// selected += 1 // modelIndex += 1
// fmt.println(selected) // sdl.ReleaseGPUBuffer(device, gndIbuf)
// modelIndex += 1 // sdl.ReleaseGPUBuffer(device, gndVbuf)
// sdl.ReleaseGPUBuffer(device, gndIbuf) // for texture in gndTextures do sdl.ReleaseGPUTexture(device, texture.texture)
// sdl.ReleaseGPUBuffer(device, gndVbuf) // gndVbuf, gndIbuf, gndTextures = loadGndModel(device, &gndModel, &gndVertices, &gndIndices, &gndNodes)
// for texture in gndTextures do sdl.ReleaseGPUTexture(device, texture.texture) // }
// gndVbuf, gndIbuf, gndTextures = loadGndModel(device, &gndModel, &gndVertices, &gndIndices, &gndNodes)
}
} }
} }
@ -859,15 +749,8 @@ runGame :: proc(window: ^sdl.Window, device: ^sdl.GPUDevice, pipeline: ^sdl.GPUG
node := mesh.node node := mesh.node
pc := Push_Constants{} pc := Push_Constants{}
flip_zy := matrix[4,4]f32{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, -1, 0,
0, 0, 0, 1,
}
pc.mvp = vp_mat * flip_zy pc.mvp = vp_mat * linalg.MATRIX4F32_IDENTITY
pc.color = [4]f32{1, 0, 0, 1.0} pc.color = [4]f32{1, 0, 0, 1.0}
sdl.BindGPUFragmentSamplers(rp, 0, &(sdl.GPUTextureSamplerBinding{ sdl.BindGPUFragmentSamplers(rp, 0, &(sdl.GPUTextureSamplerBinding{
@ -897,9 +780,8 @@ renderModel :: proc(models: ^[dynamic]format.RSM_Model, elapsed_ms: f64, nodes:
sdl.BindGPUVertexBuffers(rp, 0, &vb_binding, 1) sdl.BindGPUVertexBuffers(rp, 0, &vb_binding, 1)
ib_binding := sdl.GPUBufferBinding{buffer = ibufs[mesh.ibufIndex], offset = 0} ib_binding := sdl.GPUBufferBinding{buffer = ibufs[mesh.ibufIndex], offset = 0}
sdl.BindGPUIndexBuffer(rp, ib_binding, ._16BIT) sdl.BindGPUIndexBuffer(rp, ib_binding, ._16BIT)
model := &models[mesh.modelIndex]
model := &models[mesh.modelIndex]
animation_length := model.animation_length animation_length := model.animation_length
fps := model.frames_per_second fps := model.frames_per_second
frame_delay : f32 frame_delay : f32
@ -917,7 +799,7 @@ renderModel :: proc(models: ^[dynamic]format.RSM_Model, elapsed_ms: f64, nodes:
current_frame := u32(f32(elapsed_ms) / frame_delay) % total_frames current_frame := u32(f32(elapsed_ms) / frame_delay) % total_frames
node := mesh.node node := mesh.node
R := linalg.matrix4_rotate(linalg.to_radians(node.rotation_angle), node.rotation_axis) rotation := linalg.quaternion_angle_axis(node.rotation_angle, node.rotation_axis)
if len(node.rotation_keyframes) > 0 { if len(node.rotation_keyframes) > 0 {
keyframe_idx := 0 keyframe_idx := 0
@ -929,10 +811,12 @@ renderModel :: proc(models: ^[dynamic]format.RSM_Model, elapsed_ms: f64, nodes:
} }
q := node.rotation_keyframes[keyframe_idx].quaternion q := node.rotation_keyframes[keyframe_idx].quaternion
R = linalg.matrix4_from_quaternion(quaternion(imag=q[0], jmag=q[1], kmag=q[2], real=q[3])) rotation = quaternion(imag=q[0], jmag=q[1], kmag=q[2], real=q[3])
} }
S := linalg.matrix4_scale(node.scale) rotation = linalg.quaternion_normalize(rotation)
scale := node.scale
if len(node.scale_keyframes) > 0 { if len(node.scale_keyframes) > 0 {
keyframe_idx := 0 keyframe_idx := 0
for i := 0; i < len(node.scale_keyframes); i+= 1 { for i := 0; i < len(node.scale_keyframes); i+= 1 {
@ -941,7 +825,7 @@ renderModel :: proc(models: ^[dynamic]format.RSM_Model, elapsed_ms: f64, nodes:
keyframe_idx = i keyframe_idx = i
} else do break } else do break
} }
S = linalg.matrix4_scale(node.scale_keyframes[keyframe_idx].scale) scale = node.scale_keyframes[keyframe_idx].scale
} }
translation := [3]f32{0,0,0} translation := [3]f32{0,0,0}
@ -956,29 +840,26 @@ renderModel :: proc(models: ^[dynamic]format.RSM_Model, elapsed_ms: f64, nodes:
translation = node.translation_keyframes[keyframe_idx].translation translation = node.translation_keyframes[keyframe_idx].translation
} }
// r = linalg.identity(matrix[3,3]f32) r := linalg.matrix3_from_quaternion(rotation)
O := linalg.MATRIX4F32_IDENTITY
for c in 0..<3 { s := matrix[3,3]f32{
for r in 0..<3 { scale[0], 0, 0 ,
O[c][r] = node.offset_matrix[r][c] 0, scale[1], 0 ,
} 0, 0, scale[2],
} }
T := linalg.matrix4_translate((node.translation1 + node.translation2 + translation)) a3 := r * node.offset_matrix * s
// T = linalg.identity(matrix[4,4]f32) t := node.translation1 + node.translation2 + translation
// 4x4 affine matrix
if strings.contains(node.node_name, "patch") { model_mat := matrix[4,4]f32{
// fmt.println(node.node_name) a3[0][0], a3[0][1], a3[0][2], t[0],
continue a3[1][0], a3[1][1], a3[1][2], t[1],
} else { a3[2][0], a3[2][1], a3[2][2], t[2],
// fmt.println(node.rotation_axis) 0, 0, 0, 1 ,
} }
model_mat := T * R * O * S
pc := Push_Constants{} pc := Push_Constants{}
pc.mvp = vp_mat * mesh.transform * model_mat pc.mvp = vp_mat * mesh.transform * model_mat

View file

@ -148,7 +148,7 @@ main :: proc() {
primitive_type = .TRIANGLELIST, primitive_type = .TRIANGLELIST,
rasterizer_state = sdl.GPURasterizerState{ rasterizer_state = sdl.GPURasterizerState{
fill_mode = .FILL, fill_mode = .FILL,
cull_mode = .NONE, cull_mode = .BACK,
front_face = .COUNTER_CLOCKWISE, front_face = .COUNTER_CLOCKWISE,
depth_bias_constant_factor = 0, depth_bias_constant_factor = 0,
depth_bias_clamp = 0, depth_bias_clamp = 0,
@ -192,8 +192,8 @@ main :: proc() {
pipeline_create_info := sdl.GPUGraphicsPipelineCreateInfo{ pipeline_create_info := sdl.GPUGraphicsPipelineCreateInfo{
primitive_type = .TRIANGLELIST, primitive_type = .TRIANGLELIST,
rasterizer_state = { rasterizer_state = {
fill_mode = .FILL, fill_mode = .LINE,
cull_mode = .NONE, cull_mode = .FRONT,
} }
} }