From 66a7649a54cd8ec73198d709d0f44eb2750da934 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sat, 4 May 2024 17:48:19 +0100 Subject: [PATCH] Beginning work on integrating actual j3o objects --- .gitignore | 7 +++ ...ourneyman.simulated-genetics.launcher.html | 4 +- ...n.simulated-genetics.makehuman-bridge.html | 5 +- docs/codox/index.html | 2 +- docs/codox/intro.html | 63 ++++++++++++++++++- resources/model-prototypes/README.md | 24 +++++++ .../simulated_genetics/launcher.clj | 9 ++- 7 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 resources/model-prototypes/README.md diff --git a/.gitignore b/.gitignore index 9adaaa3..a3ea30f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/resources/jme3 /target /classes /checkouts @@ -17,3 +18,9 @@ pom.xml.asc .hg/ *.so + +*.blend* + +resources/model-prototypes/*male.glb + +resources/model-prototypes/*male.j3o diff --git a/docs/codox/cc.journeyman.simulated-genetics.launcher.html b/docs/codox/cc.journeyman.simulated-genetics.launcher.html index 0d308bd..919b2c3 100644 --- a/docs/codox/cc.journeyman.simulated-genetics.launcher.html +++ b/docs/codox/cc.journeyman.simulated-genetics.launcher.html @@ -2,7 +2,7 @@ ""> cc.journeyman.simulated-genetics.launcher documentation

cc.journeyman.simulated-genetics.launcher

TODO: write docs

-main

(-main & args)

Start an app into which generated characters can ultimately be rendered.

-

app

TODO: write docs

-

cli-options

I haven’t yet thought out what command line arguments (if any) I need. This is a placeholder.

+

app

TODO: write docs

+

cli-options

I haven’t yet thought out what command line arguments (if any) I need. This is a placeholder.

init

(init)

Again, placeholder. This initialises a bit of standard jMonkeyEngine terrain, just to check I have things wired up correctly.

\ No newline at end of file diff --git a/docs/codox/cc.journeyman.simulated-genetics.makehuman-bridge.html b/docs/codox/cc.journeyman.simulated-genetics.makehuman-bridge.html index cf615dc..3fcdce6 100644 --- a/docs/codox/cc.journeyman.simulated-genetics.makehuman-bridge.html +++ b/docs/codox/cc.journeyman.simulated-genetics.makehuman-bridge.html @@ -1,6 +1,7 @@ -cc.journeyman.simulated-genetics.makehuman-bridge documentation

cc.journeyman.simulated-genetics.makehuman-bridge

Bridge to MakeHuman, in an attempt to use it to generate character models.

+cc.journeyman.simulated-genetics.makehuman-bridge documentation

cc.journeyman.simulated-genetics.makehuman-bridge

Bridge to MakeHuman, in an attempt to use it to generate character models.

NOTE: Currently not under active development. I’ve failed to get this to work, but, even if I succeeded, it would be a very complex and fragile solution.

initialise-makehuman!

(initialise-makehuman! mh-path)

Initialise the local instance of MakeHuman. mh-path should be a valid path to the directory in which MakeHuman is installed, i.e. the directory which contains makehuman.py.

-
\ No newline at end of file +

initialize-makehuman!

macro

(initialize-makehuman! mh-path)

For those who don’t know how to spell…

+
\ No newline at end of file diff --git a/docs/codox/index.html b/docs/codox/index.html index b54eca2..ff558db 100644 --- a/docs/codox/index.html +++ b/docs/codox/index.html @@ -3,5 +3,5 @@ Simulated-genetics 0.1.0-SNAPSHOT

Simulated-genetics 0.1.0-SNAPSHOT

Released under the GNU General Public License,version 2.0 or (at your option) any later version

A lightweight simulation of genetics, intended for use in games only.

Installation

To install, add the following dependency to your project or build file:

[simulated-genetics "0.1.0-SNAPSHOT"]

Topics

Namespaces

cc.journeyman.simulated-genetics.launcher

TODO: write docs

Public variables and functions:

cc.journeyman.simulated-genetics.makehuman-bridge

Bridge to MakeHuman, in an attempt to use it to generate character models.

-

Public variables and functions:

\ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html index ff3b1cf..993d8e1 100644 --- a/docs/codox/intro.html +++ b/docs/codox/intro.html @@ -1,5 +1,66 @@ Introduction to simulated-genetics

Introduction to simulated-genetics

-

TODO: write great documentation

+

simulated-genetics

+

A clojure library (OK, at this moment it’s an app, but that’s during development only) to generate character models for games, such that characters who are represented as related to one another will have systematically similar appearance, as creatures of natural species (including humans) do. This is specifically NOT simulating genetics on any deep or quasi-scientific level, just experimenting to see how adequate a solution can be achieved with simple code and limited data.

+

Part of The Great Game project.

+

Status

+

Very pre-alpha.

+

Concept

+

If we’re going to have a world with a multi-generational population of hundreds of thousands of procedurally generated characters, and we’re to persuasively represent each character as being related to others, then we have to have a mechanism for making children look reasonably like their parents, to have family resemblances among cousins, and so on. We need to do this at reasonably low data storage and algorithmic cost, firstly because we have to store all these characters, and secondly because (especially when the player approaches an urban centre), we may need to instantiate models for a lot of them in limited time.

+

This note discusses how this might be done.

+

The pseudo-genome

+

Suppose we have a binary vector of memory, such that when a ‘child’ was born to two parents, bits were taken at random from the parents’ chromosomes to populate the child’s genome – which is sort of, very roughly, what happens in actual biology – how big would that genome have to be? After all, the full data size of the human genetic code is enormous. But actually, we don’t need to simulate anything like so large. After all, all our genome needs to encode is morphology, and only sufficiently to enable the player to recognise and distinguish characters.

+

My hunch is that a 64 bit genome is more than sufficient, if we code it carefully. So here’s how such a genome might be structured:

+ + + + + + + + + + + + + + +
Field Bits Interpretation
Ethnic type 4 Ethnic type. Most significant bits both indicate dark skin, with ??11 indicating dark skin/curly hair and ??01 indicating dark skin/straight hair
Skin tone 3 Plus most significant bit from ethnic type (i.e. ???1) as most significant bit. This means sixteen distinct tones, with the darkest tone of ‘pale skinned’ ethnicities just very slightly lighter than the palest tone of ‘dark skinned’ ethnicities.
Freckles? 2 11 means freckles, any other value means no freckles. Freckles won’t be visible on very dark skin.
Hair colour 3 Plus most significant bit from ethnic type (i.e. ???1) as most significant bit. Least significant bit does not contribute to tone but indicates red tint. Thus eight distinct degrees of darkness from pale blond to black, plus red tint which can affect any degree of darkness.
Eye colour 2 Plus most significant bit from ethnic type (i.e. ???1) as most significant bit. Thus eight values: 000 blue; 001 hazel; 010111 shades of brown lighter->darker.
Height 3 Height when adult; children will have a scaled proportion of their adult height, and the same height value in the genome will result in female body models 95% the height of an equivalent male body model. So 000 codes for 150mm, 111 codes for 200mm, with eight distinct values
Gracility/Robustness 3 Slenderness to stockiness of skeleton/armature build, with 000 being very slender and 111 being very broad/heavy.
Age-related change 3 People get white haired at different ages; some men go bald and some do not. The sons of the daughter of a bald man should have a chance of inheriting age-related baldness, although their mother won’t express that gene. So I’m allowing here for eight different profiles for age related change, although I’m not yet clear what the exact values would mean.
+

That’s twenty-nine of our sixty-four bits, leaving plenty for face models, gender and so on.

+

What’s not included in the genome

+

Things which are cultural are not included in the genome; things which are lifestyle related are not included in the genome. So, for example, gracility/robustness, is not the same as skinniness/fatness, which are mostly lifestyle/diet related rather than genetic. There are some occupations (e.g., blacksmith) where you’d be unlikely to be fat (but might be very robust). Also, the same character might grow fatter (or thinner) over time.

+

Similarly, hairstyle and beard-wearing are cultural (and occupational) rather than genetic, and closely related to choice of clothing. So while we do need to represent these things, they’re not things which should be represented in the genome.

+

Injury-related change – which would especially affect soldiers and outlaws especially but could affect any character – also needs to be encoded somehow (and may cause real problems), but this is also not a problem for the genome.

+

What additionally might be included in the pseudo-genome

+

There is a variable I’m proposing for non-player characters that I’m calling disposition, which has a range of values between -5 (surly) and +5 (sunny), which stands in for the general friendliness of the character towards random strangers, their generosity, their optimism, their degree of compassion, and so on. I don’t personally believe these things are genetic – I believe they’re nurture, not nature – but I believe that they are nevertheless inherited through families to some extent.

+

If we made a character’s setting for disposition a function of their parents’ dispositions, then that would need to be an entirely unrelated value from the physical appearance values, because otherwise you would end up having some racial appearances being friendlier and more optimistic than others, which would lead to accusations of racism and other bad things. This is simulated genetics, not simulated phrenology!

+

I mean, you may be planning the sort of game in which there are races like orcs or kobolds or whatever which are systematically less friendly and generous than characters of other races, in which case you might want to fork this library and change this decision, but if so:

+

a. that’s on you; and b. I politely suggest that you might want to examine your own attitudes.

+

Making this all work

+

NOTE: At this stage none of this works.

+

The Python ecosystem

+

MakeHuman exposes an API which allows at least many of the morphological changes required by the pseudo-genome to be applied to a human model.

+

There’s a well regarded library, libpython-clj, which allows calling of Python code from Clojure code. So in theory it should be possible to make this work.

+

If not, there are other human-model-morphing libraries out there, e.g. ManuelBastioniLab, but they’re mainly also in Python. In the worst case, the heavy lifting is in the data, and it might be possible to rewrite the code thatmorphs the data into Clojure. However, development of ManuelBastioniLAB ceased in 2018, and although there are forks available on GitHub and elsewhere, none of them seem to be active.

+

Maud

+

While things in the Python ecosystem are very polished, getting them to play nicely with Clojure/Java is non-trivial. There’s a less-polished but apparently-functional character editor built using jMonkeyEngine frameworks called Maud. This might be an easier fit.

+

Installation

+

You can’t, it doesn’t (yet) work.

+

Usage

+

FIXME: explanation

+
$ java -jar simulated-genetics-0.1.0-standalone.jar [args]
+
+

Options

+

FIXME: listing of options this app accepts.

+

Examples

+

+

Bugs

+

+

Any Other Sections

+

That You Think

+

Might be Useful

+

License

+

Copyright © 2024 Simon Brooke

+

This Source Code is made available under the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.

\ No newline at end of file diff --git a/resources/model-prototypes/README.md b/resources/model-prototypes/README.md new file mode 100644 index 0000000..9410740 --- /dev/null +++ b/resources/model-prototypes/README.md @@ -0,0 +1,24 @@ +# README for model prototypes + +These files are the most basic human male and female characters created with the [MakeHuman](http://www.makehumancommunity.org/) [MPFB]() plugin for [Blender](https://www.blender.org/). At this stage, they're created by somone (me) who has absolutely no experience with Blender. They're here only to serve as proof of concept prototypes, to get the whole process bootstrapped. + +The models are intended to be nude, and bald, so that hair and clothing can be applied later (although how this will work I don't yet understand), with eyes, eyebrows, eyelashes, teeth and tongue. The `.blend` files are the original files. The `.glb` files are exported by Blender. The `.j3o` files are created by reading the `.glb` files into [Maud](https://github.com/stephengold/Maud) and saving them. They are intended to have the standard MPFB 'rig helpers'. + +At this stage, the (.glb) model when loaded into Maud, appears to be clothed, although there is nothing I have done to clothe it and the original `.blend` does not appear to be clothed in Blender. However, interestingly, when I import the `.glb` file back into blender I get only the rig, so I'm doing something wrong. + +The model prototypes that should be here are + +* female.blend +* female.glb +* female.j3o +* male.blend +* male.glb +* male.j3o + +They're not included in the git repository at present because + +1. They're large binary files; +2. They're really, really not very good; +3. You can do better yourself if you just do what I've described above. + +Once I have all this working I will probably include model prototypes in the repository. diff --git a/src/cc/journeyman/simulated_genetics/launcher.clj b/src/cc/journeyman/simulated_genetics/launcher.clj index 962ce17..32b8b4b 100644 --- a/src/cc/journeyman/simulated_genetics/launcher.clj +++ b/src/cc/journeyman/simulated_genetics/launcher.clj @@ -3,7 +3,7 @@ [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-texture material set* start + load-model load-texture material set* start terrain-lod-control terrain-quad]] [taoensso.telemere :refer [set-min-level! trace!]]) (:import (com.jme3.texture Texture$WrapMode)) @@ -61,7 +61,12 @@ load-height-map) patch-size 65 terrain (terrain-quad "my terrain" patch-size 513 - (get-height-map height-map))] + (get-height-map height-map)) + 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"))