From a528db9e8e301517f3567dea234e5f7d84f3259d Mon Sep 17 00:00:00 2001
From: Simon Brooke <simon@journeyman.cc>
Date: Sun, 19 May 2024 20:49:22 +0100
Subject: [PATCH] Work on understanding how character models are loaded.

---
 doc/Understanding-jme3-character-models.md    |  2 +
 .../simulated_genetics/launcher.clj           | 85 ++++++++++---------
 2 files changed, 46 insertions(+), 41 deletions(-)

diff --git a/doc/Understanding-jme3-character-models.md b/doc/Understanding-jme3-character-models.md
index 1b20f67..9c0c606 100644
--- a/doc/Understanding-jme3-character-models.md
+++ b/doc/Understanding-jme3-character-models.md
@@ -99,6 +99,8 @@ To be fair I don't know what proportion of subclasses of `Control` have skeleton
 
 As there are now a lot of branches to cover, I'm going to concentrate on the `SkinningControl` one, which *seems* to be the current state of the art. I haven't at this stage investigated how `AssetManager.loadModel(String)` determines which classes to instantiate when loading a model, but I'm going to assume that I can coerce my models to be loaded in a non-deprecated form.
 
+(Confirmed: I am getting instances of SkinningControls when I load models).
+
 A [`SkinningControl`](https://javadoc.jmonkeyengine.org/v3.6.1-stable/com/jme3/anim/SkinningControl.html) has a private instance variable `armature`:
 
 ```java
diff --git a/src/cc/journeyman/simulated_genetics/launcher.clj b/src/cc/journeyman/simulated_genetics/launcher.clj
index 32b8b4b..957c064 100644
--- a/src/cc/journeyman/simulated_genetics/launcher.clj
+++ b/src/cc/journeyman/simulated_genetics/launcher.clj
@@ -1,10 +1,10 @@
 (ns cc.journeyman.simulated-genetics.launcher
   (:require [clojure.tools.cli :refer [parse-opts]]
-            [jme-clj.core :refer [add-control add-to-root app-settings cam
-                                  defsimpleapp fly-cam get-height-map image
-                                  image-based-height-map load-height-map
-                                  load-model load-texture material set* start
-                                  terrain-lod-control terrain-quad]]
+            [jme-clj.core :refer [add-control add-light-to-root add-to-root app-settings attach-child bitmap-text box cam
+                                  defsimpleapp detach-all-child fly-cam geo get* get-height-map gui-node image
+                                  image-based-height-map light load-font load-height-map
+                                  load-model load-texture material root-node rotate scale set* start
+                                  terrain-lod-control terrain-quad vec3]]
             [taoensso.telemere :refer [set-min-level! trace!]])
   (:import (com.jme3.texture Texture$WrapMode))
   (:gen-class))
@@ -34,6 +34,8 @@
 
 (declare app)
 
+(def models (atom {}))
+
 (def cli-options
   "I haven't yet thought out what command line arguments (if any) I need.
    This is a placeholder."
@@ -44,44 +46,45 @@
    ["-h" "--help"]])
 
 (defn init
-  "Again, placeholder. This initialises a bit of standard jMonkeyEngine 
-   terrain, just to check I have things wired up correctly."
+  ;; cribbed from jme-clj examples/hello-asset.clj
   []
-  (set* (fly-cam) :move-speed 50)
-  (let [grass (set* (load-texture "jme3/textures/terrain/splat/grass.jpg")
-                    :wrap Texture$WrapMode/Repeat)
-        dirt (set* (load-texture "jme3/textures/terrain/splat/dirt.jpg")
-                   :wrap Texture$WrapMode/Repeat)
-        rock (set* (load-texture "jme3/textures/terrain/splat/road.jpg")
-                   :wrap Texture$WrapMode/Repeat)
-        mat (material "Common/MatDefs/Terrain/Terrain.j3md")
-        height-map-tex (load-texture
-                        "jme3/textures/terrain/splat/mountains512.png")
-        height-map (->> height-map-tex image image-based-height-map
-                        load-height-map)
-        patch-size 65
-        terrain (terrain-quad "my terrain" patch-size 513
-                              (get-height-map height-map))
+  (let [root-node   (root-node)
         mat-default (material "Common/MatDefs/Misc/ShowNormals.j3md")
-        model (trace! (load-model "model-prototypes/male.glb"))]
-    (trace! (-> model (set* :material mat-default)
-                (set* :local-translation 0.0 -5.0 -2.0)
-                (add-to-root)))
-    (-> mat
-        (set* :texture "Alpha"
-              (load-texture "jme3/textures/terrain/splat/alphamap.png"))
-        (set* :texture "Tex1" grass)
-        (set* :float "Tex1Scale" (float 64))
-        (set* :texture "Tex2" dirt)
-        (set* :float "Tex2Scale" (float 32))
-        (set* :texture "Tex3" rock)
-        (set* :float "Tex3Scale" (float 128)))
-    (-> terrain
-        (set* :material mat)
-        (set* :local-translation 0 -100 0)
-        (set* :local-scale 2 1 2)
-        (add-to-root)
-        (add-control (terrain-lod-control terrain (cam))))))
+        ;; teapot      (load-model "Models/Teapot/Teapot.obj")
+        ;; teapot      (set* teapot :material mat-default)
+        ;; root-node   (attach-child root-node teapot)
+        ;; Create a wall with a simple texture from test_data
+        ;; box         (box 2.5 2.5 1.0)
+        ;; mat-brick   (material "Common/MatDefs/Misc/Unshaded.j3md")
+        ;; texture     (load-texture "Textures/Terrain/BrickWall/BrickWall.jpg")
+        ;; mat-brick   (set* mat-brick :texture "ColorMap" texture)
+        ;; wall        (geo "Box" box)
+        ;; wall        (-> wall (set* :material mat-brick) (set* :local-translation 2.0 -2.5 0.0))
+        ;; root-node   (attach-child root-node wall)
+        ;; Display a line of text with a default font
+        gui-node    (detach-all-child (gui-node))
+        gui-font    (load-font "Interface/Fonts/Default.fnt")
+        size        (-> gui-font (get* :char-set) (get* :rendered-size))
+        hello-text  (bitmap-text gui-font false)
+        hello-text  (-> hello-text
+                        (set* :size size)
+                        (set* :text "Hello World")
+                        (set* :local-translation 300 (get* hello-text :line-height) 0))]
+    (attach-child gui-node hello-text)
+    ; Load a model from test_data (OgreXML + material + texture)
+    (let [model (load-model "model-prototypes/female.glb")]
+      (swap! models assoc :model model)
+      (println (format "Model is of type `%s`" (type model)))
+      (-> model
+          (scale 0.05 0.05 0.05)
+          (rotate 0.0 -3.0 0.0)
+          (set* :local-translation 0.0 -5.0 -2.0))
+      (attach-child root-node model))
+    ;; You must add a light to make the model visible
+    (-> (light :directional)
+        (set* :direction (vec3 -0.1 -0.7 -1.0))
+        (add-light-to-root))))
+
 
 (defsimpleapp app :init init)