packages feed

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 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"