keid-resource-gltf 0.1.0.2 → 0.1.1.0
raw patch · 3 files changed
+56/−37 lines, 3 filesdep ~geomancydep ~keid-core
Dependency ranges changed: geomancy, keid-core
Files
- ChangeLog.md +4/−0
- keid-resource-gltf.cabal +4/−4
- src/Resource/Gltf/Scene.hs +48/−33
ChangeLog.md view
@@ -1,5 +1,9 @@ # Changelog for keid-resource-gltf +## 0.1.1.0++- Scene loader updated to follow geomancy-0.3 fixes and glTF spec.+ ## 0.1.0.2 - Support Word8 index format.
keid-resource-gltf.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.38.1. -- -- see: https://github.com/sol/hpack name: keid-resource-gltf-version: 0.1.0.2+version: 0.1.1.0 synopsis: GLTF loader for Keid engine. category: Game Engine author: IC Rainbow@@ -62,10 +62,10 @@ base >=4.7 && <5 , bytestring , containers- , geomancy >=0.2.6.0+ , geomancy >=0.3.0.0 , gl-block , gltf-codec- , keid-core+ , keid-core >=0.1.11.0 , rio >=0.1.12.0 , vector default-language: GHC2021
src/Resource/Gltf/Scene.hs view
@@ -13,6 +13,7 @@ import Data.Tree qualified as Tree import Geomancy (Transform(..), quaternion) import Geomancy.Mat4 qualified as Mat4+import Geomancy.Mat4.Internal qualified as Mat4 (fromMemory) import Geomancy.Transform qualified as Transform import Geomancy.Vec3 qualified as Vec3 import RIO.Vector qualified as Vector@@ -125,9 +126,24 @@ adjustNode Stuff{..} = Stuff { sPositions = fmap applyTransform sPositions , sAttrs = fmap applyAttrTransform sAttrs- , sIndices = sIndices+ , sIndices = adjustIndices sIndices } where+ {-+ https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#instantiation++ When a mesh primitive uses any triangle-based topology (i.e., triangles, triangle strip, or triangle fan),+ the determinant of the node’s global transform defines the winding order of that primitive.++ If the determinant is a positive value, the winding order triangle faces is counterclockwise;+ in the opposite case, the winding order is clockwise.+ -}+ adjustIndices =+ if Mat4.det transform < 0 then+ Vector.reverse+ else+ id+ applyTransform pos = coerce $ Transform.apply (coerce pos) transform @@ -150,7 +166,7 @@ where go (parent, Tree.Node{rootLabel=(mmesh, node), subForest}) = let- collected = localTransform node <> parent+ collected = mconcat $ parent : nodeTransforms node in ( (mmesh, collected, node) , map (collected,) subForest@@ -210,45 +226,44 @@ Just mesh -> Right (Just mesh) -localTransform :: Node.Node -> Transform-localTransform node = mconcat- [ nodeMatrix- , nodeScale, nodeRotate, nodeTranslate- ]+nodeTransforms :: Node.Node -> [Transform]+nodeTransforms node =+ case nodeMatrix of+ -- glTF spec says matrix should not be mixed with transforms...+ Just takesPrecedence ->+ -- ...but when that happens matrix takes precedence.+ [takesPrecedence]+ Nothing ->+ catMaybes+ [ nodeTranslate+ , nodeRotate+ , nodeScale+ ] where- nodeScale = case Node.scale node of- Nothing ->- mempty- Just (sx, sy, sz) ->+ nodeScale =+ node.scale <&> \(sx, sy, sz) -> Transform.scale3 sx sy sz nodeTranslate =- case Node.translation node of- Nothing ->- mempty- Just (tx, ty, tz) ->+ node.translation <&> \(tx, ty, tz) -> Transform.translate tx ty tz - nodeRotate = case Node.rotation node of- Nothing ->- mempty- Just (qx, qy, qz, qW) ->+ nodeRotate =+ node.rotation <&> \(qx, qy, qz, qW) -> Transform.rotateQ $ quaternion qW qx qy qz - nodeMatrix = case Node.matrix node of- Nothing ->- mempty- Just (Node.NodeMatrix memoryBytes) ->- case Vector.toList memoryBytes of- [ x1, x2, x3, x4,- y1, y2, y3, y4,- z1, z2, z3, z4,- w1, w2, w3, w4 ] ->- Mat4.colMajor @Transform- x1 y1 z1 w1- x2 y2 z2 w2- x3 y3 z3 w3- x4 y4 z4 w4+ nodeMatrix =+ node.matrix <&> \(Node.NodeMatrix memoryBytes) ->+ Transform $ case Vector.toList memoryBytes of+ [ e0, e1, e2, e3,+ e4, e5, e6, e7,+ e8, e9, eA, eB,+ eC, eD, eE, eF ] ->+ Mat4.fromMemory+ e0 e1 e2 e3+ e4 e5 e6 e7+ e8 e9 eA eB+ eC eD eE eF _ -> error "Node matrix isn't 16-element"