Skip to content

Commit

Permalink
Partial Node support
Browse files Browse the repository at this point in the history
  • Loading branch information
GlennFolker committed Feb 12, 2024
1 parent 6676510 commit eb5455b
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 16 deletions.
9 changes: 2 additions & 7 deletions annotations/src/gltf/annotations/SpecProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
.build());

boolean named = spec.getAnnotation(Named.class) != null;
if(named){
builder.addField(FieldSpec
.builder(ClassName.get(String.class), "name", PUBLIC)
.addAnnotation(ClassName.get(Nullable.class))
.build());
}
if(named) builder.addField(ClassName.get(String.class), "name", PUBLIC);

var create = MethodSpec.methodBuilder("create")
.addModifiers(PUBLIC, STATIC)
Expand All @@ -118,7 +113,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
.addStatement("out.extensions = json.get($S)", "extensions")
.addStatement("out.extras = json.get($S)", "extras");

if(named) create.addStatement("out.name = json.getString($S)", "name");
if(named) create.addStatement("out.name = json.getString($S, $S)", "name", "");
for(var prop : anno.value()){
var name = prop.name();
var type = type(prop::type);
Expand Down
5 changes: 1 addition & 4 deletions src/gltfrenzy/loader/MeshSetLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ public MeshSet load(AssetManager manager, String fileName, Fi file, MeshSetParam
var scenes = manager.get(sceneName, Scenes3D.class);
var target = fileName.substring(hash + 1);

int out = scenes.meshNames.get(target, -1);
if(out == -1) throw new IllegalArgumentException("Mesh '" + target + "' not found in '" + sceneName + "'.");

return scenes.meshes.get(out);
return scenes.meshNames.getThrow(target, () -> new IllegalArgumentException("Mesh '" + target + "' not found in '" + sceneName + "'."));
}

@Override
Expand Down
52 changes: 52 additions & 0 deletions src/gltfrenzy/loader/NodeLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package gltfrenzy.loader;

import arc.assets.*;
import arc.assets.loaders.*;
import arc.files.*;
import arc.struct.*;
import gltfrenzy.loader.NodeLoader.*;
import gltfrenzy.loader.Scenes3DLoader.*;
import gltfrenzy.model.*;

/**
* Convenience loader to automatically fetch a mesh by-name from a {@link Scenes3D}.
* @author GlennFolker
*/
public class NodeLoader extends SynchronousAssetLoader<Node, NodeParameter>{
public NodeLoader(FileHandleResolver resolver){
super(resolver);
}

@Override
public Node load(AssetManager manager, String fileName, Fi file, NodeParameter parameter){
int hash = fileName.indexOf('#');
if(hash == -1) throw new IllegalArgumentException("Invalid file name '" + fileName + "', expected 'path/to/model#node-name'");

var sceneName = fileName.substring(0, hash);
var scenes = manager.get(sceneName, Scenes3D.class);
var target = fileName.substring(hash + 1);

return scenes.nodeNames.getThrow(target, () -> new IllegalArgumentException("Node '" + target + "' not found in '" + sceneName + "'."));
}

@Override
@SuppressWarnings("rawtypes")
public Seq<AssetDescriptor> getDependencies(String fileName, Fi file, NodeParameter parameter){
int hash = fileName.indexOf('#');
if(hash == -1) throw new IllegalArgumentException("Invalid file name '" + fileName + "', expected 'path/to/model#node-name'");

return Seq.with(new AssetDescriptor<>(resolve(fileName.substring(0, hash)), Scenes3D.class, parameter == null ? null : parameter.sceneParameter));
}

public static class NodeParameter extends AssetLoaderParameters<Node>{
public Scenes3DParameter sceneParameter;

public NodeParameter(){
this(null);
}

public NodeParameter(Scenes3DParameter sceneParameter){
this.sceneParameter = sceneParameter;
}
}
}
41 changes: 39 additions & 2 deletions src/gltfrenzy/loader/Scenes3DLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import gltfrenzy.loader.Scenes3DReader.*;
import gltfrenzy.model.*;
import gltfrenzy.model.MeshSet.*;
import gltfrenzy.model.Node;

import java.io.*;
import java.nio.*;
Expand All @@ -26,6 +27,7 @@ public class Scenes3DLoader extends AsynchronousAssetLoader<Scenes3D, Scenes3DPa
protected final Scenes3DReader reader;
protected Scenes3D asset;
protected MeshContainerQueue[] meshes;
protected int[] nodeMeshes;

public Scenes3DLoader(FileHandleResolver resolver, Scenes3DReader reader){
super(resolver);
Expand Down Expand Up @@ -65,7 +67,7 @@ public void loadAsync(AssetManager manager, String fileName, Fi file, Scenes3DPa
for(int i = 0; i < meshes.length; i++){
var mesh = spec.meshes[i];
var cont = meshes[i] = new MeshContainerQueue();
cont.name = mesh.name == null ? "" : mesh.name;
cont.name = mesh.name;

cont.containers = new MeshQueue[mesh.primitives.length];
for(int m = 0; m < mesh.primitives.length; m++){
Expand Down Expand Up @@ -182,6 +184,36 @@ public void loadAsync(AssetManager manager, String fileName, Fi file, Scenes3DPa
queue.mode = primitives.mode;
}
}

// TODO Handle skin and bone weights.
nodeMeshes = new int[spec.nodes.length];
for(int i = 0; i < spec.nodes.length; i++){
var out = new Node();
var node = spec.nodes[i];

out.name = node.name;
nodeMeshes[i] = node.mesh;

if(node.matrix == null){
out.localTrns.translation.set(node.translation);
out.localTrns.rotation.set(node.rotation);
out.localTrns.scale.set(node.scale);
}else{
node.matrix.getTranslation(out.localTrns.translation);
node.matrix.getRotation(out.localTrns.rotation);
node.matrix.getScale(out.localTrns.scale);
}

asset.nodes.add(out);
if(!out.name.isEmpty()) asset.nodeNames.put(out.name, out);
}

for(int i = 0; i < asset.nodes.size; i++){
var node = asset.nodes.get(i);
node.children.each(c -> c.parent = node);
}

asset.nodes.each(Node::update);
}

@Override
Expand Down Expand Up @@ -217,11 +249,16 @@ public Scenes3D loadSync(AssetManager manager, String fileName, Fi file, Scenes3
}

out.meshes.add(set);
if(!set.name.isEmpty()) out.meshNames.put(set.name, out.meshes.size - 1);
if(!set.name.isEmpty()) out.meshNames.put(set.name, set);
}

for(int i = 0; i < nodeMeshes.length; i++){
out.nodes.get(i).mesh = out.meshes.get(i);
}

asset = null;
meshes = null;
nodeMeshes = null;
return out;
}

Expand Down
3 changes: 2 additions & 1 deletion src/gltfrenzy/model/MeshSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public MeshSet(){}

@Override
public void dispose(){
for(var cont : containers) cont.dispose();
containers.each(MeshContainer::dispose);
containers.clear();
}

public static class MeshContainer implements Disposable{
Expand Down
49 changes: 49 additions & 0 deletions src/gltfrenzy/model/Node.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package gltfrenzy.model;

import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;

/**
* Defines an object node in the hierarchy tree. Children of this node inherits its transform.
* @author GlennFolker
*/
public class Node{
private static final Mat3D mat = new Mat3D();

public String name = "";
public final Seq<Node> children = new Seq<>();
public @Nullable Node parent;

public final Transform localTrns = new Transform();
public final Mat3D globalTrns = new Mat3D();

public MeshSet mesh;

public void update(){
if(parent != null){
globalTrns.set(parent.globalTrns).mul(localTrns.matrix(mat));
}else{
localTrns.matrix(globalTrns);
}

children.each(Node::update);
}

public static class Transform{
public final Vec3 translation = new Vec3();
public final Quat rotation = new Quat();
public final Vec3 scale = new Vec3(1f, 1f, 1f);

public Transform set(Transform from){
translation.set(from.translation);
rotation.set(from.rotation);
scale.set(from.scale);
return this;
}

public Mat3D matrix(Mat3D out){
return out.set(translation, rotation, scale);
}
}
}
7 changes: 6 additions & 1 deletion src/gltfrenzy/model/Scenes3D.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
*/
public class Scenes3D implements Disposable{
public final Seq<MeshSet> meshes = new Seq<>();
public final ObjectIntMap<String> meshNames = new ObjectIntMap<>();
public final ObjectMap<String, MeshSet> meshNames = new ObjectMap<>();

public final Seq<Node> nodes = new Seq<>();
public final ObjectMap<String, Node> nodeNames = new ObjectMap<>();
public final IntSeq rootNodes = new IntSeq();

@Override
public void dispose(){
meshes.each(MeshSet::dispose);
meshes.clear();
}
}
2 changes: 1 addition & 1 deletion src/gltfrenzy/spec/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@Prop(name = "camera", type = int.class),
@Prop(name = "children", type = int[].class),
@Prop(name = "skin", type = int.class),
@Prop(name = "matrix", type = Mat3D.class, def = @Def(value = "new $T()", args = Mat3D.class)),
@Prop(name = "matrix", type = Mat3D.class),
@Prop(name = "mesh", type = int.class),
@Prop(name = "rotation", type = Quat.class, def = @Def(value = "new $T()", args = Quat.class)),
@Prop(name = "scale", type = Vec3.class, def = @Def(value = "new $T(1f, 1f, 1f)", args = Vec3.class)),
Expand Down

0 comments on commit eb5455b

Please sign in to comment.