From 74a7150cffd3a48d99e558c480fa6af4e5f71237 Mon Sep 17 00:00:00 2001 From: Gustl22 <user.rebo@gmx.de> Date: Thu, 30 Aug 2018 10:21:35 +0200 Subject: [PATCH] Replace SharedModel with ModelInstance --- .../oscim/test/gdx/poi3d/GdxModelLayer.java | 25 +- .../test/gdx/poi3d/GdxModelRenderer.java | 5 +- .../oscim/test/gdx/poi3d/GdxRenderer3D.java | 5 +- .../oscim/test/gdx/poi3d/GdxRenderer3D2.java | 5 +- .../org/oscim/test/gdx/poi3d/Poi3DLayer.java | 23 +- .../org/oscim/test/gdx/poi3d/SharedModel.java | 555 ------------------ 6 files changed, 34 insertions(+), 584 deletions(-) delete mode 100644 vtm-playground/src/org/oscim/test/gdx/poi3d/SharedModel.java diff --git a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelLayer.java b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelLayer.java index ba332093..738aef5b 100644 --- a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelLayer.java +++ b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelLayer.java @@ -2,6 +2,7 @@ package org.oscim.test.gdx.poi3d; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.model.Node; import org.oscim.core.MapPosition; @@ -60,8 +61,8 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { // TileSet mTileSet = new TileSet(); // TileSet mPrevTiles = new TileSet(); // - // LinkedHashMap<Tile, Array<SharedModel>> mTileMap = - // new LinkedHashMap<Tile, Array<SharedModel>>(); + // LinkedHashMap<Tile, Array<ModelInstance>> mTileMap = + // new LinkedHashMap<Tile, Array<ModelInstance>>(); boolean loading; Model mModel; @@ -95,7 +96,7 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { // if (ev == Map.CLEAR_EVENT) { // mTileSet = new TileSet(); // mPrevTiles = new TileSet(); - // mTileMap = new LinkedHashMap<Tile, Array<SharedModel>>(); + // mTileMap = new LinkedHashMap<Tile, Array<ModelInstance>>(); // synchronized (g3d) { // g3d.instances.clear(); // } @@ -104,11 +105,11 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { if (loading && assets.update()) { doneLoading(); // Renderable renderable = new Renderable(); - // new SharedModel(mModel).getRenderable(renderable); + // new ModelInstance(mModel).getRenderable(renderable); // Shader shader = new DefaultShader(renderable, true, false, // false, false, 1, 0, 0, 0); - g3d.instances.add(new SharedModel(mModel)); + g3d.instances.add(new ModelInstance(mModel)); } if (loading) @@ -133,15 +134,15 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { // // boolean changed = false; // - // Array<SharedModel> added = new Array<SharedModel>(); - // Array<SharedModel> removed = new Array<SharedModel>(); + // Array<ModelInstance> added = new Array<ModelInstance>(); + // Array<ModelInstance> removed = new Array<ModelInstance>(); // for (int i = 0; i < mTileSet.cnt; i++) { // MapTile t = mTileSet.tiles[i]; // if (mPrevTiles.contains(t)) // continue; // - // Array<SharedModel> instances = new Array<SharedModel>(); + // Array<ModelInstance> instances = new Array<ModelInstance>(); // // Poi3DTileData ld = (Poi3DTileData) t.getData(POI_DATA); // if (ld == null) @@ -149,7 +150,7 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { // // for (SymbolItem it : ld.symbols) { // - // SharedModel inst = new SharedModel(mModel); + // ModelInstance inst = new ModelInstance(mModel); // inst.userData = it; // // float r = 0.5f + 0.5f * (float) Math.random(); // // float g = 0.5f + 0.5f * (float) Math.random(); @@ -178,7 +179,7 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { // if (mTileSet.contains(t)) // continue; // - // Array<SharedModel> instances = mTileMap.get(t); + // Array<ModelInstance> instances = mTileMap.get(t); // if (instances == null) // continue; // @@ -208,13 +209,13 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener { // // synchronized (g3d) { // - // for (Entry<Tile, Array<SharedModel>> e : mTileMap.entrySet()) { + // for (Entry<Tile, Array<ModelInstance>> e : mTileMap.entrySet()) { // Tile t = e.getKey(); // // float dx = (float) (t.tileX * Tile.SIZE - tileX); // float dy = (float) (t.tileY * Tile.SIZE - tileY); // - // for (SharedModel inst : e.getValue()) { + // for (ModelInstance inst : e.getValue()) { // SymbolItem it = (SymbolItem) inst.userData; // // // variable height diff --git a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelRenderer.java b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelRenderer.java index 7a6c7637..e1651f25 100644 --- a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelRenderer.java +++ b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxModelRenderer.java @@ -3,6 +3,7 @@ package org.oscim.test.gdx.poi3d; import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.Renderable; import com.badlogic.gdx.graphics.g3d.Shader; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; @@ -36,7 +37,7 @@ public class GdxModelRenderer extends LayerRenderer { public Environment lights; - public Array<SharedModel> instances = new Array<SharedModel>(); + public Array<ModelInstance> instances = new Array<>(); public Shader shader; public RenderContext renderContext; @@ -151,7 +152,7 @@ public class GdxModelRenderer extends LayerRenderer { mBatch.begin(cam); //shader.begin(cam, renderContext); - for (SharedModel instance : instances) { + for (ModelInstance instance : instances) { instance.transform.getTranslation(tempVector); //instance.getRenderables(renderables, pool); // if (tempVector.x * tempVector.x + tempVector.y * tempVector.y > sqRadius) diff --git a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D.java b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D.java index 967e8af1..2c427a89 100644 --- a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D.java +++ b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D.java @@ -3,6 +3,7 @@ package org.oscim.test.gdx.poi3d; import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.Renderable; import com.badlogic.gdx.graphics.g3d.Shader; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; @@ -38,7 +39,7 @@ public class GdxRenderer3D extends LayerRenderer { public Environment lights; - public Array<SharedModel> instances = new Array<SharedModel>(); + public Array<ModelInstance> instances = new Array<>(); public Shader shader; public RenderContext renderContext; @@ -160,7 +161,7 @@ public class GdxRenderer3D extends LayerRenderer { shader.begin(cam, renderContext); - for (SharedModel instance : instances) { + for (ModelInstance instance : instances) { instance.transform.getTranslation(tempVector); if (tempVector.x * tempVector.x + tempVector.y * tempVector.y > sqRadius) diff --git a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D2.java b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D2.java index 2e77acb0..e4b23861 100644 --- a/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D2.java +++ b/vtm-playground/src/org/oscim/test/gdx/poi3d/GdxRenderer3D2.java @@ -2,6 +2,7 @@ package org.oscim.test.gdx.poi3d; import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight; import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider; import com.badlogic.gdx.math.Vector3; @@ -31,7 +32,7 @@ public class GdxRenderer3D2 extends LayerRenderer { public Environment lights; - public Array<SharedModel> instances = new Array<SharedModel>(); + public Array<ModelInstance> instances = new Array<>(); public GdxRenderer3D2(Map map) { mMap = map; @@ -132,7 +133,7 @@ public class GdxRenderer3D2 extends LayerRenderer { modelBatch.begin(cam); cnt = instances.size; - for (SharedModel instance : instances) { + for (ModelInstance instance : instances) { instance.transform.getTranslation(tempVector); tempVector.scl(0.9f, 0.9f, 1); if (!GeometryUtils.pointInPoly(tempVector.x, tempVector.y, mBox, 8, 0)) diff --git a/vtm-playground/src/org/oscim/test/gdx/poi3d/Poi3DLayer.java b/vtm-playground/src/org/oscim/test/gdx/poi3d/Poi3DLayer.java index 22c69148..319cb768 100644 --- a/vtm-playground/src/org/oscim/test/gdx/poi3d/Poi3DLayer.java +++ b/vtm-playground/src/org/oscim/test/gdx/poi3d/Poi3DLayer.java @@ -2,6 +2,7 @@ package org.oscim.test.gdx.poi3d; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.model.Node; import com.badlogic.gdx.utils.Array; @@ -99,8 +100,8 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { TileSet mTileSet = new TileSet(); TileSet mPrevTiles = new TileSet(); - LinkedHashMap<Tile, Array<SharedModel>> mTileMap = - new LinkedHashMap<Tile, Array<SharedModel>>(); + LinkedHashMap<Tile, Array<ModelInstance>> mTileMap = + new LinkedHashMap<>(); boolean loading; Model mModel; @@ -127,7 +128,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { if (ev == Map.CLEAR_EVENT) { mTileSet = new TileSet(); mPrevTiles = new TileSet(); - mTileMap = new LinkedHashMap<Tile, Array<SharedModel>>(); + mTileMap = new LinkedHashMap<>(); synchronized (g3d) { g3d.instances.clear(); } @@ -136,7 +137,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { if (loading && assets.update()) { doneLoading(); // Renderable renderable = new Renderable(); - // new SharedModel(mModel).getRenderable(renderable); + // new ModelInstance(mModel).getRenderable(renderable); // Shader shader = new DefaultShader(renderable, true, false, // false, false, 1, 0, 0, 0); } @@ -154,15 +155,15 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { boolean changed = false; - Array<SharedModel> added = new Array<SharedModel>(); - Array<SharedModel> removed = new Array<SharedModel>(); + Array<ModelInstance> added = new Array<>(); + Array<ModelInstance> removed = new Array<>(); for (int i = 0; i < mTileSet.cnt; i++) { MapTile t = mTileSet.tiles[i]; if (mPrevTiles.contains(t)) continue; - Array<SharedModel> instances = new Array<SharedModel>(); + Array<ModelInstance> instances = new Array<>(); Poi3DTileData ld = (Poi3DTileData) t.getData(POI_DATA); if (ld == null) @@ -170,7 +171,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { for (SymbolItem it : ld.symbols) { - SharedModel inst = new SharedModel(mModel); + ModelInstance inst = new ModelInstance(mModel); inst.userData = it; // float r = 0.5f + 0.5f * (float) Math.random(); // float g = 0.5f + 0.5f * (float) Math.random(); @@ -199,7 +200,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { if (mTileSet.contains(t)) continue; - Array<SharedModel> instances = mTileMap.get(t); + Array<ModelInstance> instances = mTileMap.get(t); if (instances == null) continue; @@ -229,13 +230,13 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener { synchronized (g3d) { - for (Entry<Tile, Array<SharedModel>> e : mTileMap.entrySet()) { + for (Entry<Tile, Array<ModelInstance>> e : mTileMap.entrySet()) { Tile t = e.getKey(); float dx = (float) (t.tileX * Tile.SIZE - tileX); float dy = (float) (t.tileY * Tile.SIZE - tileY); - for (SharedModel inst : e.getValue()) { + for (ModelInstance inst : e.getValue()) { SymbolItem it = (SymbolItem) inst.userData; // variable height diff --git a/vtm-playground/src/org/oscim/test/gdx/poi3d/SharedModel.java b/vtm-playground/src/org/oscim/test/gdx/poi3d/SharedModel.java deleted file mode 100644 index 946ea1c6..00000000 --- a/vtm-playground/src/org/oscim/test/gdx/poi3d/SharedModel.java +++ /dev/null @@ -1,555 +0,0 @@ -package org.oscim.test.gdx.poi3d; - -import com.badlogic.gdx.graphics.g3d.Material; -import com.badlogic.gdx.graphics.g3d.Model; -import com.badlogic.gdx.graphics.g3d.ModelBatch; -import com.badlogic.gdx.graphics.g3d.Renderable; -import com.badlogic.gdx.graphics.g3d.RenderableProvider; -import com.badlogic.gdx.graphics.g3d.model.Animation; -import com.badlogic.gdx.graphics.g3d.model.MeshPart; -import com.badlogic.gdx.graphics.g3d.model.Node; -import com.badlogic.gdx.graphics.g3d.model.NodeAnimation; -import com.badlogic.gdx.graphics.g3d.model.NodeKeyframe; -import com.badlogic.gdx.graphics.g3d.model.NodePart; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.BoundingBox; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.ArrayMap; -import com.badlogic.gdx.utils.ObjectMap; -import com.badlogic.gdx.utils.Pool; - -/** - * An instance of a {@link Model}, allows to specify global transform and modify the materials, as it - * has a copy of the model's materials. Multiple instances can be created from the same Model, - * all sharing the meshes and textures of the Model. The Model owns the meshes and textures, to - * dispose of these, the Model has to be disposed. Therefor, the Model must outlive all its ModelInstances</p> - * <p/> - * The ModelInstance creates a full copy of all materials, nodes and animations. - * - * @author badlogic, xoppa - */ -public class SharedModel implements RenderableProvider { - /** - * the materials of the model, used by nodes that have a graphical representation FIXME not sure if superfluous, allows modification of materials without having to traverse the nodes - **/ - public final Array<Material> materials = new Array<Material>(); - /** - * root nodes of the model - **/ - public final Array<Node> nodes = new Array<Node>(); - /** - * animations of the model, modifying node transformations - **/ - public final Array<Animation> animations = new Array<Animation>(); - /** - * the {@link Model} this instances derives from - **/ - public final Model model; - /** - * the world transform - **/ - public Matrix4 transform; - /** - * user definable value, which is passed to the shader. - */ - public Object userData; - - /** - * Constructs a new ModelInstance with all nodes and materials of the given model. - * - * @param model The {@link Model} to create an instance of. - */ - public SharedModel(final Model model) { - this(model, (String[]) null); - } - - /** - * @param model The source {@link Model} - * @param nodeId The ID of the root {@link Node} of the {@link Model} for the instance to contain - * @param mergeTransform True to apply the source node transform to the instance transform, resetting the node transform. - */ - public SharedModel(final Model model, final String nodeId, boolean mergeTransform) { - this(model, null, nodeId, false, false, mergeTransform); - } - - /** - * @param model The source {@link Model} - * @param transform The {@link Matrix4} instance for this ModelInstance to reference or null to create a new matrix. - * @param nodeId The ID of the root {@link Node} of the {@link Model} for the instance to contain - * @param mergeTransform True to apply the source node transform to the instance transform, resetting the node transform. - */ - public SharedModel(final Model model, final Matrix4 transform, final String nodeId, boolean mergeTransform) { - this(model, transform, nodeId, false, false, mergeTransform); - } - - /** - * Recursively searches the mode for the specified node. - * - * @param model The source {@link Model} - * @param nodeId The ID of the {@link Node} within the {@link Model} for the instance to contain - * @param parentTransform True to apply the parent's node transform to the instance (only applicable if recursive is true). - * @param mergeTransform True to apply the source node transform to the instance transform, resetting the node transform. - */ - public SharedModel(final Model model, final String nodeId, boolean parentTransform, boolean mergeTransform) { - this(model, null, nodeId, true, parentTransform, mergeTransform); - } - - /** - * Recursively searches the mode for the specified node. - * - * @param model The source {@link Model} - * @param transform The {@link Matrix4} instance for this ModelInstance to reference or null to create a new matrix. - * @param nodeId The ID of the {@link Node} within the {@link Model} for the instance to contain - * @param parentTransform True to apply the parent's node transform to the instance (only applicable if recursive is true). - * @param mergeTransform True to apply the source node transform to the instance transform, resetting the node transform. - */ - public SharedModel(final Model model, final Matrix4 transform, final String nodeId, boolean parentTransform, boolean mergeTransform) { - this(model, transform, nodeId, true, parentTransform, mergeTransform); - } - - /** - * @param model The source {@link Model} - * @param nodeId The ID of the {@link Node} within the {@link Model} for the instance to contain - * @param recursive True to recursively search the Model's node tree, false to only search for a root node - * @param parentTransform True to apply the parent's node transform to the instance (only applicable if recursive is true). - * @param mergeTransform True to apply the source node transform to the instance transform, resetting the node transform. - */ - public SharedModel(final Model model, final String nodeId, boolean recursive, boolean parentTransform, boolean mergeTransform) { - this(model, null, nodeId, recursive, parentTransform, mergeTransform); - } - - /** - * @param model The source {@link Model} - * @param transform The {@link Matrix4} instance for this ModelInstance to reference or null to create a new matrix. - * @param nodeId The ID of the {@link Node} within the {@link Model} for the instance to contain - * @param recursive True to recursively search the Model's node tree, false to only search for a root node - * @param parentTransform True to apply the parent's node transform to the instance (only applicable if recursive is true). - * @param mergeTransform True to apply the source node transform to the instance transform, resetting the node transform. - */ - public SharedModel(final Model model, final Matrix4 transform, final String nodeId, boolean recursive, boolean parentTransform, boolean mergeTransform) { - this.model = model; - this.transform = transform == null ? new Matrix4() : transform; - nodePartBones.clear(); - Node copy, node = model.getNode(nodeId, recursive); - this.nodes.add(copy = copyNode(node)); - if (mergeTransform) { - this.transform.mul(parentTransform ? node.globalTransform : node.localTransform); - copy.translation.set(0, 0, 0); - copy.rotation.idt(); - copy.scale.set(1, 1, 1); - } else if (parentTransform && copy.hasParent()) - this.transform.mul(node.getParent().globalTransform); - setBones(); - copyAnimations(model.animations); - calculateTransforms(); - } - - /** - * Constructs a new ModelInstance with only the specified nodes and materials of the given model. - */ - public SharedModel(final Model model, final String... rootNodeIds) { - this(model, null, rootNodeIds); - } - - /** - * Constructs a new ModelInstance with only the specified nodes and materials of the given model. - */ - public SharedModel(final Model model, final Matrix4 transform, final String... rootNodeIds) { - this.model = model; - this.transform = transform == null ? new Matrix4() : transform; - if (rootNodeIds == null) - copyNodes(model.nodes); - else - copyNodes(model.nodes, rootNodeIds); - copyAnimations(model.animations); - calculateTransforms(); - } - - /** - * Constructs a new ModelInstance with only the specified nodes and materials of the given model. - */ - public SharedModel(final Model model, final Array<String> rootNodeIds) { - this(model, null, rootNodeIds); - } - - /** - * Constructs a new ModelInstance with only the specified nodes and materials of the given model. - */ - public SharedModel(final Model model, final Matrix4 transform, final Array<String> rootNodeIds) { - this.model = model; - this.transform = transform == null ? new Matrix4() : transform; - copyNodes(model.nodes, rootNodeIds); - copyAnimations(model.animations); - calculateTransforms(); - } - - /** - * Constructs a new ModelInstance at the specified position. - */ - public SharedModel(final Model model, Vector3 position) { - this(model); - this.transform.setToTranslation(position); - } - - /** - * Constructs a new ModelInstance at the specified position. - */ - public SharedModel(final Model model, float x, float y, float z) { - this(model); - this.transform.setToTranslation(x, y, z); - } - - /** - * Constructs a new ModelInstance with the specified transform. - */ - public SharedModel(final Model model, Matrix4 transform) { - this(model, transform, (String[]) null); - } - - /** - * Constructs a new ModelInstance which is an copy of the specified ModelInstance. - */ - public SharedModel(SharedModel copyFrom) { - this(copyFrom, copyFrom.transform.cpy()); - } - - /** - * Constructs a new ModelInstance which is an copy of the specified ModelInstance. - */ - public SharedModel(SharedModel copyFrom, final Matrix4 transform) { - this.model = copyFrom.model; - this.transform = transform == null ? new Matrix4() : transform; - copyNodes(copyFrom.nodes); - copyAnimations(copyFrom.animations); - calculateTransforms(); - } - - /** - * @return A newly created ModelInstance which is a copy of this ModelInstance - */ - public SharedModel copy() { - return new SharedModel(this); - } - - private ObjectMap<NodePart, ArrayMap<Node, Matrix4>> nodePartBones = new ObjectMap<NodePart, ArrayMap<Node, Matrix4>>(); - - private void copyNodes(Array<Node> nodes) { - nodePartBones.clear(); - for (int i = 0, n = nodes.size; i < n; ++i) { - final Node node = nodes.get(i); - this.nodes.add(copyNode(node)); - } - setBones(); - } - - private void copyNodes(Array<Node> nodes, final String... nodeIds) { - nodePartBones.clear(); - for (int i = 0, n = nodes.size; i < n; ++i) { - final Node node = nodes.get(i); - for (final String nodeId : nodeIds) { - if (nodeId.equals(node.id)) { - this.nodes.add(copyNode(node)); - break; - } - } - } - setBones(); - } - - private void copyNodes(Array<Node> nodes, final Array<String> nodeIds) { - nodePartBones.clear(); - for (int i = 0, n = nodes.size; i < n; ++i) { - final Node node = nodes.get(i); - for (final String nodeId : nodeIds) { - if (nodeId.equals(node.id)) { - this.nodes.add(copyNode(node)); - break; - } - } - } - setBones(); - } - - private void setBones() { - for (ObjectMap.Entry<NodePart, ArrayMap<Node, Matrix4>> e : nodePartBones.entries()) { - if (e.key.invBoneBindTransforms == null) - e.key.invBoneBindTransforms = new ArrayMap<Node, Matrix4>(true, e.value.size, Node.class, Matrix4.class); - e.key.invBoneBindTransforms.clear(); - - for (final ObjectMap.Entry<Node, Matrix4> b : e.value.entries()) - e.key.invBoneBindTransforms.put(getNode(b.key.id), b.value); // Share the inv bind matrix with the model - - e.key.bones = new Matrix4[e.value.size]; - for (int i = 0; i < e.key.bones.length; i++) - e.key.bones[i] = new Matrix4(); - } - } - - private Node copyNode(Node node) { - Node copy = new Node(); - copy.id = node.id; - copy.inheritTransform = node.inheritTransform; - copy.translation.set(node.translation); - copy.rotation.set(node.rotation); - copy.scale.set(node.scale); - copy.localTransform.set(node.localTransform); - copy.globalTransform.set(node.globalTransform); - for (NodePart nodePart : node.parts) { - copy.parts.add(copyNodePart(nodePart)); - } - for (Node child : node.getChildren()) { - copy.addChild(copyNode(child)); - } - return copy; - } - - private NodePart copyNodePart(NodePart nodePart) { - NodePart copy = new NodePart(); - copy.meshPart = new MeshPart(); - copy.meshPart.id = nodePart.meshPart.id; - copy.meshPart.offset = nodePart.meshPart.offset; - copy.meshPart.size = nodePart.meshPart.size; - copy.meshPart.primitiveType = nodePart.meshPart.primitiveType; - copy.meshPart.mesh = nodePart.meshPart.mesh; - - if (nodePart.invBoneBindTransforms != null) - nodePartBones.put(copy, nodePart.invBoneBindTransforms); - -// final int index = materials.indexOf(nodePart.material, false); -// if (index < 0) -// materials.add(copy.material = nodePart.material.copy()); -// else -// copy.material = materials.get(index); -// - copy.material = nodePart.material; - - return copy; - } - - private void copyAnimations(final Iterable<Animation> source) { - for (final Animation anim : source) { - Animation animation = new Animation(); - animation.id = anim.id; - for (final NodeAnimation nanim : anim.nodeAnimations) { - final Node node = getNode(nanim.node.id); - if (node == null) - continue; - NodeAnimation nodeAnim = new NodeAnimation(); - nodeAnim.node = node; - if (nanim.rotation != null) { - nodeAnim.rotation = new Array<NodeKeyframe<Quaternion>>(); - nodeAnim.rotation.ensureCapacity(nanim.rotation.size); - for (final NodeKeyframe<Quaternion> kf : nanim.rotation) { - if (kf.keytime > animation.duration) - animation.duration = kf.keytime; - nodeAnim.rotation.add(new NodeKeyframe<Quaternion>(kf.keytime, new Quaternion(kf.value == null ? node.rotation : kf.value))); - } - } - if (nanim.scaling != null) { - nodeAnim.scaling = new Array<NodeKeyframe<Vector3>>(); - nodeAnim.scaling.ensureCapacity(nanim.scaling.size); - for (final NodeKeyframe<Vector3> kf : nanim.scaling) { - if (kf.keytime > animation.duration) - animation.duration = kf.keytime; - nodeAnim.scaling.add(new NodeKeyframe<Vector3>(kf.keytime, new Vector3(kf.value == null ? node.scale : kf.value))); - } - } - if (nanim.translation != null) { - nodeAnim.translation = new Array<NodeKeyframe<Vector3>>(); - nodeAnim.translation.ensureCapacity(nanim.translation.size); - for (final NodeKeyframe<Vector3> kf : nanim.translation) { - if (kf.keytime > animation.duration) - animation.duration = kf.keytime; - nodeAnim.translation.add(new NodeKeyframe<Vector3>(kf.keytime, new Vector3(kf.value == null ? node.translation : kf.value))); - } - } - if ((nodeAnim.rotation != null && nodeAnim.rotation.size > 0) - || (nodeAnim.scaling != null && nodeAnim.scaling.size > 0) - || (nodeAnim.translation != null && nodeAnim.translation.size > 0)) - animation.nodeAnimations.add(nodeAnim); - } - if (animation.nodeAnimations.size > 0) - animations.add(animation); - } - } - - - /** - * Traverses the Node hierarchy and collects {@link Renderable} instances for every - * node with a graphical representation. Renderables are obtained from the provided - * pool. The resulting array can be rendered via a {@link ModelBatch}. - * - * @param renderables the output array - * @param pool the pool to obtain Renderables from - */ - public void getRenderables(Array<Renderable> renderables, Pool<Renderable> pool) { - for (Node node : nodes) { - getRenderables(node, renderables, pool); - } - } - - /** - * @return The renderable of the first node's first part. - */ - public Renderable getRenderable(final Renderable out) { - return getRenderable(out, nodes.get(0)); - } - - /** - * @return The renderable of the node's first part. - */ - public Renderable getRenderable(final Renderable out, final Node node) { - return getRenderable(out, node, node.parts.get(0)); - } - - public Renderable getRenderable(final Renderable out, final Node node, final NodePart nodePart) { - nodePart.setRenderable(out); - if (nodePart.bones == null && transform != null) - out.worldTransform.set(transform).mul(node.globalTransform); - else if (transform != null) - out.worldTransform.set(transform); - else - out.worldTransform.idt(); - out.userData = userData; - return out; - } - - protected void getRenderables(Node node, Array<Renderable> renderables, Pool<Renderable> pool) { - if (node.parts.size > 0) { - for (NodePart nodePart : node.parts) { - renderables.add(getRenderable(pool.obtain(), node, nodePart)); - } - } - - for (Node child : node.getChildren()) { - getRenderables(child, renderables, pool); - } - } - - /** - * Calculates the local and world transform of all {@link Node} instances in this model, recursively. - * First each {@link Node#localTransform} transform is calculated based on the translation, rotation and - * scale of each Node. Then each {@link Node#calculateWorldTransform()} - * is calculated, based on the parent's world transform and the local transform of each Node. - * Finally, the animation bone matrices are updated accordingly.</p> - * <p/> - * This method can be used to recalculate all transforms if any of the Node's local properties (translation, rotation, scale) - * was modified. - */ - public void calculateTransforms() { - final int n = nodes.size; - for (int i = 0; i < n; i++) { - nodes.get(i).calculateTransforms(true); - } - for (int i = 0; i < n; i++) { - nodes.get(i).calculateBoneTransforms(true); - } - } - - /** - * Calculate the bounding box of this model instance. - * This is a potential slow operation, it is advised to cache the result. - * - * @param out the {@link BoundingBox} that will be set with the bounds. - * @return the out parameter for chaining - */ - public BoundingBox calculateBoundingBox(final BoundingBox out) { - out.inf(); - return extendBoundingBox(out); - } - - /** - * Extends the bounding box with the bounds of this model instance. - * This is a potential slow operation, it is advised to cache the result. - * - * @param out the {@link BoundingBox} that will be extended with the bounds. - * @return the out parameter for chaining - */ - public BoundingBox extendBoundingBox(final BoundingBox out) { - final int n = nodes.size; - for (int i = 0; i < n; i++) - nodes.get(i).extendBoundingBox(out); - return out; - } - - /** - * @param id The ID of the animation to fetch (case sensitive). - * @return The {@link Animation} with the specified id, or null if not available. - */ - public Animation getAnimation(final String id) { - return getAnimation(id, true); - } - - /** - * @param id The ID of the animation to fetch. - * @param ignoreCase whether to use case sensitivity when comparing the animation id. - * @return The {@link Animation} with the specified id, or null if not available. - */ - public Animation getAnimation(final String id, boolean ignoreCase) { - final int n = animations.size; - Animation animation; - if (ignoreCase) { - for (int i = 0; i < n; i++) - if ((animation = animations.get(i)).id.equalsIgnoreCase(id)) - return animation; - } else { - for (int i = 0; i < n; i++) - if ((animation = animations.get(i)).id.equals(id)) - return animation; - } - return null; - } - -// /** @param id The ID of the material to fetch. -// * @return The {@link Material} with the specified id, or null if not available. */ -// public Material getMaterial(final String id) { -// return getMaterial(id, true); -// } -// -// /** @param id The ID of the material to fetch. -// * @param ignoreCase whether to use case sensitivity when comparing the material id. -// * @return The {@link Material} with the specified id, or null if not available. */ -// public Material getMaterial(final String id, boolean ignoreCase) { -// final int n = materials.size; -// Material material; -// if (ignoreCase) { -// for (int i = 0; i < n; i++) -// if ((material = materials.get(i)).id.equalsIgnoreCase(id)) -// return material; -// } else { -// for (int i = 0; i < n; i++) -// if ((material = materials.get(i)).id.equals(id)) -// return material; -// } -// return null; -// } - - /** - * @param id The ID of the node to fetch. - * @return The {@link Node} with the specified id, or null if not found. - */ - public Node getNode(final String id) { - return getNode(id, true); - } - - /** - * @param id The ID of the node to fetch. - * @param recursive false to fetch a root node only, true to search the entire node tree for the specified node. - * @return The {@link Node} with the specified id, or null if not found. - */ - public Node getNode(final String id, boolean recursive) { - return getNode(id, recursive, false); - } - - /** - * @param id The ID of the node to fetch. - * @param recursive false to fetch a root node only, true to search the entire node tree for the specified node. - * @param ignoreCase whether to use case sensitivity when comparing the node id. - * @return The {@link Node} with the specified id, or null if not found. - */ - public Node getNode(final String id, boolean recursive, boolean ignoreCase) { - return Node.getNode(nodes, id, recursive, ignoreCase); - } -}