-
-
Notifications
You must be signed in to change notification settings - Fork 218
Entity model node system #2824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Entity model node system #2824
Changes from all commits
21aacfa
8284574
088cd06
020422b
37adbae
a8fba76
61e9795
acc5c1b
9a3e70e
bafca57
93bd094
5fbf9ba
c2e7539
8f3bd44
0a32373
0fe9857
60254d9
a912431
9af0011
2dbc78e
1e04fa3
ac18860
1b44749
baae55c
033c645
3932133
927849b
c962389
87b048a
82a8004
c58f1e5
9fa8825
aadf9e8
74608ef
b913a8b
a37c7e3
1a7328a
9dce456
de078f2
eb21a65
6b9f57b
56c2574
c7d52e6
c8f7e64
dc533fc
a772887
4f63e05
ab3bdd7
3fb2f7a
03aebf4
3a2bf28
9466192
1e10d2f
af029e6
afe5680
160a389
95ebdef
3185949
727832b
952accc
86aeb70
2ec1523
f4d25de
25d8919
8a2fab4
adb9c24
79e5665
9894803
91d8304
30a315a
2b66994
95aecd3
1b2b067
208c1a3
3168010
98248b1
08e749b
ab59a4a
54d678b
bd23a6b
cf25ddb
60406fb
ae922bc
20bc311
d261a3e
df89778
7d6c5d9
1f796d4
debaa7d
1e77f98
c2ad96a
b944b65
a93e11d
2717cfa
9666eeb
d016cc6
28ed7c0
5fec731
668bf16
d5c32a2
a1d4bf6
dfecb3b
a8ef1c3
47fbb3a
aa74be2
0ed025a
b01cb7b
5432f72
c0061fc
e9d3070
fe888f1
253f1b7
fa854b4
c44644b
34a7c31
7eb07c7
1fd28a9
8407584
31fe8e9
c129a63
cb431e3
fce736c
67af0be
b89505e
dbfc549
e7294f7
ae685f5
1238efc
52f36bc
9e4e6a6
381e458
b7d0a68
bc6e275
42fd688
2768938
8a1e849
8e80725
807d8b8
084543a
30c0996
41181f3
0081ea5
7bed7df
3d0418e
d007e7c
8581157
9ff6aaa
1ed66b6
0403d13
3039d14
8a5db6e
e18f348
0fecebb
03cdfeb
51553d7
84654ee
e6f4f97
20740ca
8bb00a0
b0246c4
9de1ab1
6bd6680
b1d3059
00836e6
d42c17c
8e34363
09c4c26
5247f07
5aa0ddc
23156fe
da2175f
14a7e6f
abe9640
232b581
5ac7159
fa6ba84
3cd9f82
aa4a56d
37e3fe2
66aa25e
8f9b624
aae144c
6061302
ef98a78
f17d3eb
b253c93
b3b5fc8
84caf1a
677638f
22ea1a5
a7caab8
ccd4650
f877fef
2e2a126
096eb57
e47eb77
601b319
6f21573
46b2697
a43766b
885dfac
bd5d699
05576eb
0a57121
0d7129c
23a0cc0
8fef535
4d62048
2f78bee
3759c5f
cf24fcf
c480f08
8b42c5b
89c6b96
3e7e63d
084fe12
cb0ae0a
e6e611f
89b0172
303f131
5e27e00
f550bb4
55a7958
aa139e9
fd70dc7
d11f0d4
7acbf41
5f8ed5c
fa0cc39
c486c98
659eb21
7ff1aa9
a22b916
ab1f092
b1dab22
facacbe
e598e24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,5 +5,6 @@ | |
| .model = "cubyz:snale", | ||
| .defaultTexture = "cubyz:snale", | ||
| .height = 2, | ||
| .isPlayerModel = true, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unintended change |
||
| .coordinateSystem = .left_handed_y_up, | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain what changed here? I see no difference |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |||||
| layout (location = 0) in vec3 inPos; | ||||||
| layout (location = 1) in vec3 inNormal; | ||||||
| layout (location = 2) in vec2 inUV; | ||||||
| layout (location = 3) in uint inNodeID; | ||||||
|
|
||||||
| layout(location = 0) out vec2 outTexCoord; | ||||||
| layout(location = 1) out vec3 mvVertexPos; | ||||||
|
|
@@ -13,6 +14,7 @@ layout(location = 0) uniform mat4 projectionMatrix; | |||||
| layout(location = 1) uniform mat4 viewMatrix; | ||||||
| layout(location = 2) uniform vec3 ambientLight; | ||||||
| layout(location = 3) uniform uint light; | ||||||
| layout(location = 6) uniform mat4 nodeMatrices[20]; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of limiting this to 20 nodes, please use an SSBO. (also if we wanted to have so many uniforms in Vulkan, we'd need to use a UBO, which I'm sure you don't want to touch) You can use the LargeBuffer to allocator memory for each entity, then you can use a uniform to specify the offset into the buffer. |
||||||
|
|
||||||
| vec3 square(vec3 x) { | ||||||
| return x*x; | ||||||
|
|
@@ -35,7 +37,7 @@ vec3 calcLight(uint fullLight) { | |||||
| void main() { | ||||||
| normal = inNormal; | ||||||
|
|
||||||
| vec4 mvPos = viewMatrix*vec4(inPos, 1); | ||||||
| vec4 mvPos = viewMatrix * nodeMatrices[inNodeID] * vec4(inPos, 1); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please follow the formatting style
Suggested change
|
||||||
| gl_Position = projectionMatrix*mvPos; | ||||||
| mvVertexPos = mvPos.xyz; | ||||||
| outTexCoord = inUV; | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ const Mat4f = vec.Mat4f; | |
| const Vec3d = vec.Vec3d; | ||
| const Vec3f = vec.Vec3f; | ||
| const Vec4f = vec.Vec4f; | ||
| const EntityModel = main.entityModel.EntityModel; | ||
| const NeverFailingAllocator = main.heap.NeverFailingAllocator; | ||
|
|
||
| const BinaryReader = main.utils.BinaryReader; | ||
|
|
@@ -40,6 +41,7 @@ pub fn init(self: *@This(), zon: ZonElement, allocator: NeverFailingAllocator) ! | |
| .name = allocator.dupe(u8, zon.get([]const u8, "name", "")), | ||
| .playerIndex = zon.get(?usize, "playerIndex", null), | ||
| }; | ||
|
|
||
| self._interpolationPos = [_]f64{ | ||
| self.pos[0], | ||
| self.pos[1], | ||
|
|
@@ -77,6 +79,25 @@ pub fn update(self: *@This(), time: i16, lastTime: i16) void { | |
| self.rot[0] = @floatCast(self.interpolatedValues.outPos[3]); | ||
| self.rot[1] = @floatCast(self.interpolatedValues.outPos[4]); | ||
| self.rot[2] = @floatCast(self.interpolatedValues.outPos[5]); | ||
|
|
||
| if (main.entity.components.@"cubyz:model".client.get(self.id)) |modelComp| { | ||
| const model = modelComp.entityModel.get(); | ||
|
|
||
| const head = model.nodeReverse.get("Head"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it called reverse? reverse of what? |
||
| if (model.nodeReverse.get("Eyestalks")) |eyestalksId| { | ||
| const stalkRot = self.rot[0]*0.25; | ||
| const headRot = self.rot[0]*0.75; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of hardcoding it here, could this information be stored in the model somehow? Does it allow to add named variables to the nodes, so you could add to each node how much head rotation it gets? |
||
| modelComp.nodes[eyestalksId].rot = vec.quatFromAxisAngle(Vec3f{1, 0, 0}, stalkRot); | ||
| modelComp.matrices[eyestalksId] = modelComp.nodes[eyestalksId].getHierarchyMatrix(modelComp.nodes); | ||
|
|
||
| const headId = head.?; | ||
| modelComp.nodes[headId].rot = vec.quatFromAxisAngle(Vec3f{1, 0, 0}, headRot); | ||
| modelComp.matrices[headId] = modelComp.nodes[headId].getHierarchyMatrix(modelComp.nodes); | ||
| } else if (head) |headId| { | ||
| modelComp.nodes[headId].rot = vec.quatFromAxisAngle(Vec3f{1, 0, 0}, self.rot[0]); | ||
| modelComp.matrices[headId] = modelComp.nodes[headId].getHierarchyMatrix(modelComp.nodes); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to move this code somewhere else? |
||
| } | ||
| } | ||
| } | ||
|
|
||
| pub fn format(self: *const @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,9 @@ pub const entityComponentVersion = 0; | |
| pub const client = struct { | ||
| const Component = struct { | ||
| entityModel: main.entityModel.EntityModelIndex, | ||
| hasLoaded: bool = false, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not used |
||
| nodes: [20]main.entityModel.EntityModel.Node = undefined, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't add an arbitrary limit, you are also wasting memory if you do it like that. |
||
| matrices: [20]Mat4f = undefined, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure you need to recalculate them every frame anyways (otherwise child nodes of e.g. the head won't be updated properly) , so why even store them? |
||
| }; | ||
| pub var components: main.utils.SparseSet(Component, main.entity.Entity) = .{}; | ||
|
|
||
|
|
@@ -45,6 +48,15 @@ pub const client = struct { | |
| ptr.* = Component{ | ||
| .entityModel = .{.index = entityModel}, | ||
| }; | ||
| const model = ptr.entityModel.get(); | ||
|
|
||
| for (0..model.nodeCount) |i| { | ||
| ptr.nodes[i] = model.nodes[i]; | ||
| } | ||
|
|
||
| for (0..model.nodeCount) |i| { | ||
| ptr.matrices[i] = ptr.nodes[i].getHierarchyMatrix(ptr.nodes); | ||
| } | ||
| } | ||
| pub fn unload(entity: u32) void { | ||
| components.remove(@enumFromInt(entity)) catch {}; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -27,11 +27,41 @@ pub const EntityModel = struct { | |||||
| texturePath: []const u8, | ||||||
| modelId: ?[]const u8, | ||||||
|
|
||||||
| nodeReverse: std.StringHashMap(u16) = undefined, | ||||||
| nodes: NodeList = undefined, | ||||||
| nodeCount: u8, | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does gltf really only allow for 255 nodes? |
||||||
|
|
||||||
| vao: ?graphics.VertexArray = null, | ||||||
| indexCount: c_int, | ||||||
| defaultTexture: ?main.graphics.Texture, | ||||||
| coordinateSystem: CoordinateSystem, | ||||||
|
|
||||||
| pub const maxNodesCount = 20; | ||||||
| pub const NodeList = [maxNodesCount]Node; | ||||||
| pub const MatrixList = [maxNodesCount]Mat4f; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused |
||||||
|
|
||||||
| pub const Node = struct { | ||||||
| pos: Vec3f = @splat(0), | ||||||
| rot: Vec4f = Vec4f{0, 0, 0, 1}, | ||||||
| scale: Vec3f = @splat(1), | ||||||
|
|
||||||
| originMat: Mat4f, | ||||||
|
|
||||||
| parent: ?u16 = null, | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you using different types for the node index? |
||||||
|
|
||||||
| pub fn getHierarchyMatrix(self: Node, nodes: NodeList) Mat4f { | ||||||
| var mat = self.originMat.mul(Mat4f.translation(self.pos)); | ||||||
| mat = mat.mul(Mat4f.rotationQuat(self.rot)); | ||||||
| mat = mat.mul(Mat4f.scale(self.scale)); | ||||||
|
|
||||||
| if (self.parent == null) { | ||||||
| return mat; | ||||||
| } | ||||||
|
|
||||||
| return nodes[self.parent.?].getHierarchyMatrix(nodes).mul(mat); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very inefficient way of computing all nodes. I'd suggest to use memoization to avoid recalculating parent matrices multiple times each frame, or better use a top-down approach to calulate them, starting at the root, and calculate them using child indices. |
||||||
| } | ||||||
| }; | ||||||
|
RanPix marked this conversation as resolved.
|
||||||
|
|
||||||
| pub const CoordinateSystem = enum { | ||||||
| right_handed_z_up, | ||||||
| right_handed_y_up, | ||||||
|
|
@@ -43,6 +73,7 @@ pub const EntityModel = struct { | |||||
| pos: [3]f32, | ||||||
| normal: [3]f32, | ||||||
| uv: [2]f32, | ||||||
| nodeID: c_uint, | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| pub const attributeDescriptions: []const c.VkVertexInputAttributeDescription = &.{ | ||||||
| .{ | ||||||
|
|
@@ -60,6 +91,11 @@ pub const EntityModel = struct { | |||||
| .format = c.VK_FORMAT_R32G32_SFLOAT, | ||||||
| .offset = @offsetOf(@This(), "uv"), | ||||||
| }, | ||||||
| .{ | ||||||
| .location = 3, | ||||||
| .format = c.VK_FORMAT_R32_UINT, | ||||||
| .offset = @offsetOf(@This(), "nodeID"), | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| }, | ||||||
| }; | ||||||
| }; | ||||||
|
|
||||||
|
|
@@ -76,6 +112,16 @@ pub const EntityModel = struct { | |||||
| self.indexCount = 0; | ||||||
| self.coordinateSystem = zon.get(CoordinateSystem, "coordinateSystem", .right_handed_z_up); | ||||||
|
|
||||||
| self.nodeReverse = .init(main.worldArena.allocator); | ||||||
| self.nodes = std.mem.zeroes([20]Node); | ||||||
| self.nodeCount = 0; | ||||||
|
|
||||||
| if (zon.getChildOrNull("isPlayerModel")) |isPlayerModel| { | ||||||
| if (isPlayerModel.as(bool, false)) { | ||||||
| playerEntityModels.append(main.worldArena, index); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| var isPlayerModel = false; | ||||||
| const tags = main.Tag.loadTagsFromZon(main.worldArena, zon.getChild("tags")); | ||||||
| for (tags) |tag| { | ||||||
|
|
@@ -124,6 +170,9 @@ pub const EntityModel = struct { | |||||
| .indexCount = 0, | ||||||
| .defaultTexture = null, | ||||||
| .coordinateSystem = self.coordinateSystem, | ||||||
| .nodeReverse = self.nodeReverse.clone() catch unreachable, | ||||||
| .nodes = self.nodes, | ||||||
| .nodeCount = self.nodeCount, | ||||||
| }; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -164,63 +213,96 @@ pub const EntityModel = struct { | |||||
| defer indices.deinit(); | ||||||
| var baseVertex: u32 = 0; | ||||||
|
|
||||||
| var nodeIdx: u8 = 0; | ||||||
|
|
||||||
| for (data.nodes, 0..data.nodes_count) |node, _| { | ||||||
| if (node.children_count == 0) continue; | ||||||
| const nameC = std.mem.span(node.name); | ||||||
|
|
||||||
| const name = main.globalArena.alloc(u8, nameC.len); | ||||||
| @memcpy(name, nameC); | ||||||
| self.nodeReverse.put(name, @intCast(nodeIdx)) catch unreachable; | ||||||
|
|
||||||
| var originMat = Mat4f.translation(convertCoordinateSystemVec(node.translation, self.coordinateSystem)); | ||||||
| originMat = originMat.mul(Mat4f.rotationQuat(convertCoordinateSystemQuat(node.rotation, self.coordinateSystem))); | ||||||
| originMat = originMat.mul(Mat4f.scale(convertCoordinateSystemScale(node.scale, self.coordinateSystem))); | ||||||
| self.nodes[nodeIdx] = Node{ | ||||||
| .originMat = originMat, | ||||||
| }; | ||||||
| nodeIdx += 1; | ||||||
| } | ||||||
|
|
||||||
| for (data.nodes, 0..data.nodes_count) |node, _| { | ||||||
| if (node.children_count == 0 or node.parent == null) continue; | ||||||
|
|
||||||
| const curNode = self.nodeReverse.get(std.mem.span(node.name)).?; | ||||||
| self.nodes[curNode].parent = self.nodeReverse.get(std.mem.span(node.parent.*.name)).?; | ||||||
| } | ||||||
|
|
||||||
| for (data.nodes[0..data.nodes_count]) |node| { | ||||||
| if (node.mesh != null) { | ||||||
| const finalMat = getHierarchyMatrix(node, self.coordinateSystem); | ||||||
|
|
||||||
| const primitives = node.mesh.*.primitives; | ||||||
| for (primitives[0..node.mesh.*.primitives_count]) |primitive| { | ||||||
| if (primitive.type != gltf.cgltf_primitive_type_triangles) { | ||||||
| std.log.warn("Unsupported primitive type: {d}", .{primitive.type}); | ||||||
| continue; | ||||||
| } | ||||||
| if (node.mesh == null) continue; | ||||||
|
|
||||||
| const indicesAccessor = primitive.indices.*; | ||||||
| const vertCount = primitive.attributes[0].data.*.count; | ||||||
| var indicesSlice = indices.addMany(indicesAccessor.count); | ||||||
| baseVertex = @intCast(vertices.items.len); | ||||||
| const vertSlice: []Vertex = vertices.addMany(vertCount); | ||||||
| var finalMat = Mat4f.translation(convertCoordinateSystemVec(node.translation, self.coordinateSystem)); | ||||||
| finalMat = finalMat.mul(Mat4f.rotationQuat(convertCoordinateSystemQuat(node.rotation, self.coordinateSystem))); | ||||||
| finalMat = finalMat.mul(Mat4f.scale(convertCoordinateSystemScale(node.scale, self.coordinateSystem))); | ||||||
|
|
||||||
| for (0..indicesAccessor.count) |i| { | ||||||
| const idx = indicesAccessor.read_index(i); | ||||||
| indicesSlice[i] = @as(u32, @intCast(idx)) + baseVertex; | ||||||
| } | ||||||
| const parentNodeID = if (node.parent) |p| self.nodeReverse.get(std.mem.span(p.*.name)).? else 0; | ||||||
|
|
||||||
| var positionAttr: gltf.cgltf_accessor = undefined; | ||||||
| var normalAttr: gltf.cgltf_accessor = undefined; | ||||||
| var uvAttr: gltf.cgltf_accessor = undefined; | ||||||
| for (primitive.attributes, 0..primitive.attributes_count) |attrib, _| { | ||||||
| const attribAccessor = attrib.data.*; | ||||||
|
|
||||||
| switch (attrib.type) { | ||||||
| gltf.cgltf_attribute_type_position => positionAttr = attribAccessor, | ||||||
| gltf.cgltf_attribute_type_normal => normalAttr = attribAccessor, | ||||||
| gltf.cgltf_attribute_type_texcoord => uvAttr = attribAccessor, | ||||||
| else => continue, | ||||||
| } | ||||||
| } | ||||||
| const primitives = node.mesh.*.primitives; | ||||||
| for (primitives[0..node.mesh.*.primitives_count]) |primitive| { | ||||||
| if (primitive.type != gltf.cgltf_primitive_type_triangles) { | ||||||
| std.log.warn("Unsupported primitive type: {d}", .{primitive.type}); | ||||||
| continue; | ||||||
| } | ||||||
|
|
||||||
| for (0..positionAttr.count) |v| { | ||||||
| var p: [3]f32 = undefined; | ||||||
| _ = positionAttr.read_float(v, @ptrCast(&p), 3); | ||||||
| const p2 = convertCoordinateSystemVec(p, self.coordinateSystem); | ||||||
| const pos: vec.Vec4f = finalMat.mulVec(.{p2[0], p2[1], p2[2], 1}); | ||||||
| vertSlice[v].pos = vec.xyz(pos); | ||||||
| const indicesAccessor = primitive.indices.*; | ||||||
| const vertCount = primitive.attributes[0].data.*.count; | ||||||
| var indicesSlice = indices.addMany(indicesAccessor.count); | ||||||
| baseVertex = @intCast(vertices.items.len); | ||||||
| const vertSlice: []Vertex = vertices.addMany(vertCount); | ||||||
|
|
||||||
| var normal: [3]f32 = undefined; | ||||||
| _ = normalAttr.read_float(v, @ptrCast(&normal), 3); | ||||||
| vertSlice[v].normal = convertCoordinateSystemVec(normal, self.coordinateSystem); | ||||||
| for (0..indicesAccessor.count) |i| { | ||||||
| const idx = indicesAccessor.read_index(i); | ||||||
| indicesSlice[i] = @as(u32, @intCast(idx)) + baseVertex; | ||||||
| } | ||||||
|
|
||||||
| var uv: [2]f32 = undefined; | ||||||
| _ = uvAttr.read_float(v, @ptrCast(&uv), 2); | ||||||
| vertSlice[v].uv = .{uv[0], 1 - uv[1]}; | ||||||
| var positionAttr: gltf.cgltf_accessor = undefined; | ||||||
| var normalAttr: gltf.cgltf_accessor = undefined; | ||||||
| var uvAttr: gltf.cgltf_accessor = undefined; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please make a seperate PR for just the indentation change you did here? |
||||||
| for (primitive.attributes, 0..primitive.attributes_count) |attrib, _| { | ||||||
| const attribAccessor = attrib.data.*; | ||||||
|
|
||||||
| switch (attrib.type) { | ||||||
| gltf.cgltf_attribute_type_position => positionAttr = attribAccessor, | ||||||
| gltf.cgltf_attribute_type_normal => normalAttr = attribAccessor, | ||||||
| gltf.cgltf_attribute_type_texcoord => uvAttr = attribAccessor, | ||||||
| else => continue, | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| for (0..positionAttr.count) |v| { | ||||||
| var p: [3]f32 = undefined; | ||||||
| _ = positionAttr.read_float(v, @ptrCast(&p), 3); | ||||||
| const p2 = convertCoordinateSystemVec(p, self.coordinateSystem); | ||||||
| const pos: vec.Vec4f = finalMat.mulVec(.{p2[0], p2[1], p2[2], 1}); | ||||||
| vertSlice[v].pos = vec.xyz(pos); | ||||||
|
|
||||||
| var normal: [3]f32 = undefined; | ||||||
| _ = normalAttr.read_float(v, @ptrCast(&normal), 3); | ||||||
| vertSlice[v].normal = convertCoordinateSystemVec(normal, self.coordinateSystem); | ||||||
|
|
||||||
| var uv: [2]f32 = undefined; | ||||||
| _ = uvAttr.read_float(v, @ptrCast(&uv), 2); | ||||||
| vertSlice[v].uv = .{uv[0], 1 - uv[1]}; | ||||||
|
|
||||||
| vertSlice[v].nodeID = @intCast(parentNodeID); | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| self.vao = .init(Vertex, vertices.items, indices.items); | ||||||
| self.indexCount = @intCast(indices.items.len); | ||||||
| self.nodeCount = nodeIdx; | ||||||
| } | ||||||
|
|
||||||
| fn convertCoordinateSystemVec(v: Vec3f, sys: CoordinateSystem) Vec3f { | ||||||
|
|
@@ -248,18 +330,6 @@ pub const EntityModel = struct { | |||||
| }; | ||||||
| } | ||||||
|
|
||||||
| fn getHierarchyMatrix(node: gltf.cgltf_node, sys: CoordinateSystem) Mat4f { | ||||||
| var currentMat = Mat4f.translation(convertCoordinateSystemVec(node.translation, sys)); | ||||||
| currentMat = currentMat.mul(Mat4f.rotationQuat(convertCoordinateSystemQuat(node.rotation, sys))); | ||||||
| currentMat = currentMat.mul(Mat4f.scale(convertCoordinateSystemScale(node.scale, sys))); | ||||||
|
|
||||||
| if (node.parent == null) { | ||||||
| return currentMat; | ||||||
| } | ||||||
|
|
||||||
| return getHierarchyMatrix(node.parent.*, sys).mul(currentMat); | ||||||
| } | ||||||
|
|
||||||
| fn getGltfError(result: gltf.cgltf_result) anyerror { | ||||||
| return switch (result) { | ||||||
| gltf.cgltf_result_data_too_short => error.DataTooShort, | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unintended change