Replace SharedModel with ModelInstance
This commit is contained in:
parent
3beb830baf
commit
74a7150cff
@ -2,6 +2,7 @@ package org.oscim.test.gdx.poi3d;
|
|||||||
|
|
||||||
import com.badlogic.gdx.assets.AssetManager;
|
import com.badlogic.gdx.assets.AssetManager;
|
||||||
import com.badlogic.gdx.graphics.g3d.Model;
|
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.graphics.g3d.model.Node;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
@ -60,8 +61,8 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener {
|
|||||||
// TileSet mTileSet = new TileSet();
|
// TileSet mTileSet = new TileSet();
|
||||||
// TileSet mPrevTiles = new TileSet();
|
// TileSet mPrevTiles = new TileSet();
|
||||||
//
|
//
|
||||||
// LinkedHashMap<Tile, Array<SharedModel>> mTileMap =
|
// LinkedHashMap<Tile, Array<ModelInstance>> mTileMap =
|
||||||
// new LinkedHashMap<Tile, Array<SharedModel>>();
|
// new LinkedHashMap<Tile, Array<ModelInstance>>();
|
||||||
|
|
||||||
boolean loading;
|
boolean loading;
|
||||||
Model mModel;
|
Model mModel;
|
||||||
@ -95,7 +96,7 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener {
|
|||||||
// if (ev == Map.CLEAR_EVENT) {
|
// if (ev == Map.CLEAR_EVENT) {
|
||||||
// mTileSet = new TileSet();
|
// mTileSet = new TileSet();
|
||||||
// mPrevTiles = new TileSet();
|
// mPrevTiles = new TileSet();
|
||||||
// mTileMap = new LinkedHashMap<Tile, Array<SharedModel>>();
|
// mTileMap = new LinkedHashMap<Tile, Array<ModelInstance>>();
|
||||||
// synchronized (g3d) {
|
// synchronized (g3d) {
|
||||||
// g3d.instances.clear();
|
// g3d.instances.clear();
|
||||||
// }
|
// }
|
||||||
@ -104,11 +105,11 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener {
|
|||||||
if (loading && assets.update()) {
|
if (loading && assets.update()) {
|
||||||
doneLoading();
|
doneLoading();
|
||||||
// Renderable renderable = new Renderable();
|
// Renderable renderable = new Renderable();
|
||||||
// new SharedModel(mModel).getRenderable(renderable);
|
// new ModelInstance(mModel).getRenderable(renderable);
|
||||||
// Shader shader = new DefaultShader(renderable, true, false,
|
// Shader shader = new DefaultShader(renderable, true, false,
|
||||||
// false, false, 1, 0, 0, 0);
|
// false, false, 1, 0, 0, 0);
|
||||||
|
|
||||||
g3d.instances.add(new SharedModel(mModel));
|
g3d.instances.add(new ModelInstance(mModel));
|
||||||
|
|
||||||
}
|
}
|
||||||
if (loading)
|
if (loading)
|
||||||
@ -133,15 +134,15 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener {
|
|||||||
//
|
//
|
||||||
// boolean changed = false;
|
// boolean changed = false;
|
||||||
//
|
//
|
||||||
// Array<SharedModel> added = new Array<SharedModel>();
|
// Array<ModelInstance> added = new Array<ModelInstance>();
|
||||||
// Array<SharedModel> removed = new Array<SharedModel>();
|
// Array<ModelInstance> removed = new Array<ModelInstance>();
|
||||||
|
|
||||||
// for (int i = 0; i < mTileSet.cnt; i++) {
|
// for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
// MapTile t = mTileSet.tiles[i];
|
// MapTile t = mTileSet.tiles[i];
|
||||||
// if (mPrevTiles.contains(t))
|
// if (mPrevTiles.contains(t))
|
||||||
// continue;
|
// continue;
|
||||||
//
|
//
|
||||||
// Array<SharedModel> instances = new Array<SharedModel>();
|
// Array<ModelInstance> instances = new Array<ModelInstance>();
|
||||||
//
|
//
|
||||||
// Poi3DTileData ld = (Poi3DTileData) t.getData(POI_DATA);
|
// Poi3DTileData ld = (Poi3DTileData) t.getData(POI_DATA);
|
||||||
// if (ld == null)
|
// if (ld == null)
|
||||||
@ -149,7 +150,7 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener {
|
|||||||
//
|
//
|
||||||
// for (SymbolItem it : ld.symbols) {
|
// for (SymbolItem it : ld.symbols) {
|
||||||
//
|
//
|
||||||
// SharedModel inst = new SharedModel(mModel);
|
// ModelInstance inst = new ModelInstance(mModel);
|
||||||
// inst.userData = it;
|
// inst.userData = it;
|
||||||
// // float r = 0.5f + 0.5f * (float) Math.random();
|
// // float r = 0.5f + 0.5f * (float) Math.random();
|
||||||
// // float g = 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))
|
// if (mTileSet.contains(t))
|
||||||
// continue;
|
// continue;
|
||||||
//
|
//
|
||||||
// Array<SharedModel> instances = mTileMap.get(t);
|
// Array<ModelInstance> instances = mTileMap.get(t);
|
||||||
// if (instances == null)
|
// if (instances == null)
|
||||||
// continue;
|
// continue;
|
||||||
//
|
//
|
||||||
@ -208,13 +209,13 @@ public class GdxModelLayer extends Layer implements Map.UpdateListener {
|
|||||||
//
|
//
|
||||||
// synchronized (g3d) {
|
// synchronized (g3d) {
|
||||||
//
|
//
|
||||||
// for (Entry<Tile, Array<SharedModel>> e : mTileMap.entrySet()) {
|
// for (Entry<Tile, Array<ModelInstance>> e : mTileMap.entrySet()) {
|
||||||
// Tile t = e.getKey();
|
// Tile t = e.getKey();
|
||||||
//
|
//
|
||||||
// float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
// float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||||
// float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
// float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
||||||
//
|
//
|
||||||
// for (SharedModel inst : e.getValue()) {
|
// for (ModelInstance inst : e.getValue()) {
|
||||||
// SymbolItem it = (SymbolItem) inst.userData;
|
// SymbolItem it = (SymbolItem) inst.userData;
|
||||||
//
|
//
|
||||||
// // variable height
|
// // variable height
|
||||||
|
@ -3,6 +3,7 @@ package org.oscim.test.gdx.poi3d;
|
|||||||
import com.badlogic.gdx.graphics.g3d.Environment;
|
import com.badlogic.gdx.graphics.g3d.Environment;
|
||||||
import com.badlogic.gdx.graphics.g3d.Model;
|
import com.badlogic.gdx.graphics.g3d.Model;
|
||||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
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.Renderable;
|
||||||
import com.badlogic.gdx.graphics.g3d.Shader;
|
import com.badlogic.gdx.graphics.g3d.Shader;
|
||||||
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
|
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
|
||||||
@ -36,7 +37,7 @@ public class GdxModelRenderer extends LayerRenderer {
|
|||||||
|
|
||||||
public Environment lights;
|
public Environment lights;
|
||||||
|
|
||||||
public Array<SharedModel> instances = new Array<SharedModel>();
|
public Array<ModelInstance> instances = new Array<>();
|
||||||
|
|
||||||
public Shader shader;
|
public Shader shader;
|
||||||
public RenderContext renderContext;
|
public RenderContext renderContext;
|
||||||
@ -151,7 +152,7 @@ public class GdxModelRenderer extends LayerRenderer {
|
|||||||
mBatch.begin(cam);
|
mBatch.begin(cam);
|
||||||
//shader.begin(cam, renderContext);
|
//shader.begin(cam, renderContext);
|
||||||
|
|
||||||
for (SharedModel instance : instances) {
|
for (ModelInstance instance : instances) {
|
||||||
instance.transform.getTranslation(tempVector);
|
instance.transform.getTranslation(tempVector);
|
||||||
//instance.getRenderables(renderables, pool);
|
//instance.getRenderables(renderables, pool);
|
||||||
// if (tempVector.x * tempVector.x + tempVector.y * tempVector.y > sqRadius)
|
// if (tempVector.x * tempVector.x + tempVector.y * tempVector.y > sqRadius)
|
||||||
|
@ -3,6 +3,7 @@ package org.oscim.test.gdx.poi3d;
|
|||||||
import com.badlogic.gdx.graphics.g3d.Environment;
|
import com.badlogic.gdx.graphics.g3d.Environment;
|
||||||
import com.badlogic.gdx.graphics.g3d.Model;
|
import com.badlogic.gdx.graphics.g3d.Model;
|
||||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
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.Renderable;
|
||||||
import com.badlogic.gdx.graphics.g3d.Shader;
|
import com.badlogic.gdx.graphics.g3d.Shader;
|
||||||
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
|
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
|
||||||
@ -38,7 +39,7 @@ public class GdxRenderer3D extends LayerRenderer {
|
|||||||
|
|
||||||
public Environment lights;
|
public Environment lights;
|
||||||
|
|
||||||
public Array<SharedModel> instances = new Array<SharedModel>();
|
public Array<ModelInstance> instances = new Array<>();
|
||||||
|
|
||||||
public Shader shader;
|
public Shader shader;
|
||||||
public RenderContext renderContext;
|
public RenderContext renderContext;
|
||||||
@ -160,7 +161,7 @@ public class GdxRenderer3D extends LayerRenderer {
|
|||||||
|
|
||||||
shader.begin(cam, renderContext);
|
shader.begin(cam, renderContext);
|
||||||
|
|
||||||
for (SharedModel instance : instances) {
|
for (ModelInstance instance : instances) {
|
||||||
instance.transform.getTranslation(tempVector);
|
instance.transform.getTranslation(tempVector);
|
||||||
|
|
||||||
if (tempVector.x * tempVector.x + tempVector.y * tempVector.y > sqRadius)
|
if (tempVector.x * tempVector.x + tempVector.y * tempVector.y > sqRadius)
|
||||||
|
@ -2,6 +2,7 @@ package org.oscim.test.gdx.poi3d;
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.g3d.Environment;
|
import com.badlogic.gdx.graphics.g3d.Environment;
|
||||||
import com.badlogic.gdx.graphics.g3d.ModelBatch;
|
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.environment.DirectionalLight;
|
||||||
import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider;
|
import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider;
|
||||||
import com.badlogic.gdx.math.Vector3;
|
import com.badlogic.gdx.math.Vector3;
|
||||||
@ -31,7 +32,7 @@ public class GdxRenderer3D2 extends LayerRenderer {
|
|||||||
|
|
||||||
public Environment lights;
|
public Environment lights;
|
||||||
|
|
||||||
public Array<SharedModel> instances = new Array<SharedModel>();
|
public Array<ModelInstance> instances = new Array<>();
|
||||||
|
|
||||||
public GdxRenderer3D2(Map map) {
|
public GdxRenderer3D2(Map map) {
|
||||||
mMap = map;
|
mMap = map;
|
||||||
@ -132,7 +133,7 @@ public class GdxRenderer3D2 extends LayerRenderer {
|
|||||||
modelBatch.begin(cam);
|
modelBatch.begin(cam);
|
||||||
cnt = instances.size;
|
cnt = instances.size;
|
||||||
|
|
||||||
for (SharedModel instance : instances) {
|
for (ModelInstance instance : instances) {
|
||||||
instance.transform.getTranslation(tempVector);
|
instance.transform.getTranslation(tempVector);
|
||||||
tempVector.scl(0.9f, 0.9f, 1);
|
tempVector.scl(0.9f, 0.9f, 1);
|
||||||
if (!GeometryUtils.pointInPoly(tempVector.x, tempVector.y, mBox, 8, 0))
|
if (!GeometryUtils.pointInPoly(tempVector.x, tempVector.y, mBox, 8, 0))
|
||||||
|
@ -2,6 +2,7 @@ package org.oscim.test.gdx.poi3d;
|
|||||||
|
|
||||||
import com.badlogic.gdx.assets.AssetManager;
|
import com.badlogic.gdx.assets.AssetManager;
|
||||||
import com.badlogic.gdx.graphics.g3d.Model;
|
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.graphics.g3d.model.Node;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
@ -99,8 +100,8 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener {
|
|||||||
TileSet mTileSet = new TileSet();
|
TileSet mTileSet = new TileSet();
|
||||||
TileSet mPrevTiles = new TileSet();
|
TileSet mPrevTiles = new TileSet();
|
||||||
|
|
||||||
LinkedHashMap<Tile, Array<SharedModel>> mTileMap =
|
LinkedHashMap<Tile, Array<ModelInstance>> mTileMap =
|
||||||
new LinkedHashMap<Tile, Array<SharedModel>>();
|
new LinkedHashMap<>();
|
||||||
|
|
||||||
boolean loading;
|
boolean loading;
|
||||||
Model mModel;
|
Model mModel;
|
||||||
@ -127,7 +128,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener {
|
|||||||
if (ev == Map.CLEAR_EVENT) {
|
if (ev == Map.CLEAR_EVENT) {
|
||||||
mTileSet = new TileSet();
|
mTileSet = new TileSet();
|
||||||
mPrevTiles = new TileSet();
|
mPrevTiles = new TileSet();
|
||||||
mTileMap = new LinkedHashMap<Tile, Array<SharedModel>>();
|
mTileMap = new LinkedHashMap<>();
|
||||||
synchronized (g3d) {
|
synchronized (g3d) {
|
||||||
g3d.instances.clear();
|
g3d.instances.clear();
|
||||||
}
|
}
|
||||||
@ -136,7 +137,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener {
|
|||||||
if (loading && assets.update()) {
|
if (loading && assets.update()) {
|
||||||
doneLoading();
|
doneLoading();
|
||||||
// Renderable renderable = new Renderable();
|
// Renderable renderable = new Renderable();
|
||||||
// new SharedModel(mModel).getRenderable(renderable);
|
// new ModelInstance(mModel).getRenderable(renderable);
|
||||||
// Shader shader = new DefaultShader(renderable, true, false,
|
// Shader shader = new DefaultShader(renderable, true, false,
|
||||||
// false, false, 1, 0, 0, 0);
|
// false, false, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@ -154,15 +155,15 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener {
|
|||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
|
|
||||||
Array<SharedModel> added = new Array<SharedModel>();
|
Array<ModelInstance> added = new Array<>();
|
||||||
Array<SharedModel> removed = new Array<SharedModel>();
|
Array<ModelInstance> removed = new Array<>();
|
||||||
|
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
MapTile t = mTileSet.tiles[i];
|
MapTile t = mTileSet.tiles[i];
|
||||||
if (mPrevTiles.contains(t))
|
if (mPrevTiles.contains(t))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Array<SharedModel> instances = new Array<SharedModel>();
|
Array<ModelInstance> instances = new Array<>();
|
||||||
|
|
||||||
Poi3DTileData ld = (Poi3DTileData) t.getData(POI_DATA);
|
Poi3DTileData ld = (Poi3DTileData) t.getData(POI_DATA);
|
||||||
if (ld == null)
|
if (ld == null)
|
||||||
@ -170,7 +171,7 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener {
|
|||||||
|
|
||||||
for (SymbolItem it : ld.symbols) {
|
for (SymbolItem it : ld.symbols) {
|
||||||
|
|
||||||
SharedModel inst = new SharedModel(mModel);
|
ModelInstance inst = new ModelInstance(mModel);
|
||||||
inst.userData = it;
|
inst.userData = it;
|
||||||
// float r = 0.5f + 0.5f * (float) Math.random();
|
// float r = 0.5f + 0.5f * (float) Math.random();
|
||||||
// float g = 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))
|
if (mTileSet.contains(t))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Array<SharedModel> instances = mTileMap.get(t);
|
Array<ModelInstance> instances = mTileMap.get(t);
|
||||||
if (instances == null)
|
if (instances == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -229,13 +230,13 @@ public class Poi3DLayer extends Layer implements Map.UpdateListener {
|
|||||||
|
|
||||||
synchronized (g3d) {
|
synchronized (g3d) {
|
||||||
|
|
||||||
for (Entry<Tile, Array<SharedModel>> e : mTileMap.entrySet()) {
|
for (Entry<Tile, Array<ModelInstance>> e : mTileMap.entrySet()) {
|
||||||
Tile t = e.getKey();
|
Tile t = e.getKey();
|
||||||
|
|
||||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||||
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
||||||
|
|
||||||
for (SharedModel inst : e.getValue()) {
|
for (ModelInstance inst : e.getValue()) {
|
||||||
SymbolItem it = (SymbolItem) inst.userData;
|
SymbolItem it = (SymbolItem) inst.userData;
|
||||||
|
|
||||||
// variable height
|
// variable height
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user