package scene3d; import com.badlogic.gdx.graphics.g2d.Batch; 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.math.Matrix4; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.SnapshotArray; public class Group3d extends Actor3d{ private final SnapshotArray<Actor3d> children = new SnapshotArray<Actor3d>(true, 4, Actor3d.class); public int visibleCount; public Group3d(){ super(); } public Group3d(Model model){ super(model); } public void act (float delta) { super.act(delta); Actor3d[] actors = children.begin(); for(int i = 0, n = children.size; i < n; i++){ actors[i].act(delta); } children.end(); } /** Draws the group and its children. The default implementation calls {@link #applyTransform(Batch, Matrix4)} if needed, then * {@link #drawChildren(Batch, float)}, then {@link #resetTransform(Batch)} if needed. */ @Override public void draw(ModelBatch modelBatch, Environment environment) { super.draw(modelBatch, environment); drawChildren(modelBatch, environment); } public void drawChildren(ModelBatch modelBatch, Environment environment){ //modelBatch.render(children, environment); maybe faster SnapshotArray<Actor3d> children = this.children; Actor3d[] actors = children.begin(); visibleCount = 0; for (int i = 0, n = children.size; i < n; i++){ if(actors[i] instanceof Group3d){ ((Group3d) actors[i]).drawChildren(modelBatch, environment); } else{ float offsetX = x, offsetY = y, offsetZ = z; float offsetScaleX = scaleX, offsetScaleY = scaleY, offsetScaleZ = scaleZ; float offsetYaw = yaw, offsetPitch = pitch, offsetRoll = roll; x = 0; y = 0; z = 0; scaleX = 0; scaleY = 0; scaleZ = 0; yaw = 0; pitch = 0; roll = 0; Actor3d child = actors[i]; if (!child.isVisible()) continue; /*Matrix4 diff = sub(child.getTransform(), getTransform()); Matrix4 childMatrix = child.getTransform().cpy(); child.getTransform().set(add(diff, childMatrix)); child.draw(modelBatch, environment);*/ float cx = child.x, cy = child.y, cz = child.z; float sx = child.scaleX, sy = child.scaleY, sz = child.scaleZ; float ry = child.yaw, rp = child.pitch, rr = child.roll; //child.x = cx + offsetX; //child.y = cy + offsetY; //child.z = cz + offsetZ; child.setPosition(cx + offsetX, cy + offsetY, cz + offsetZ); child.setScale(sx + offsetScaleX, sy + offsetScaleY, sz + offsetScaleZ); child.setRotation(ry + offsetYaw, rp + offsetPitch, rr +offsetRoll); if (child.isCullable(getStage3d().getCamera())) { child.draw(modelBatch, environment); visibleCount++; } child.x = cx; child.y = cy; child.z = cz; x = offsetX; y = offsetY; z = offsetZ; child.scaleX = sx; child.scaleY = sy; child.scaleZ = sz; scaleX = offsetScaleX; scaleY = offsetScaleY; scaleZ = offsetScaleZ; child.yaw = ry; child.pitch = rp; child.roll = rr; yaw = offsetYaw; pitch = offsetPitch; roll = offsetRoll; } } children.end(); } /** Adds an actor as a child of this group. The actor is first removed from its parent group, if any. * @see #remove() */ public void addActor3d(Actor3d actor3d) { actor3d.remove(); children.add(actor3d); actor3d.setParent(this); actor3d.setStage3d(getStage3d()); childrenChanged(); } /** Removes an actor from this group. If the actor will not be used again and has actions, they should be * {@link Actor#clearActions3d() cleared} so the actions will be returned to their * {@link Action#setPool(com.badlogic.gdx.utils.Pool) pool}, if any. This is not done automatically. */ public boolean removeActor3d(Actor3d actor3d) { if (!children.removeValue(actor3d, true)) return false; Stage3d stage = getStage3d(); if (stage != null) stage.unfocus(actor3d); actor3d.setParent(null); actor3d.setStage3d(null); childrenChanged(); return true; } /** Called when actors are added to or removed from the group. */ protected void childrenChanged () { } /** Removes all actors from this group. */ public void clearChildren () { Actor3d[] actors = children.begin(); for (int i = 0, n = children.size; i < n; i++) { Actor3d child = actors[i]; child.setStage3d(null); child.setParent(null); } children.end(); children.clear(); childrenChanged(); } /** Removes all children, actions, and listeners from this group. */ public void clear () { super.clear(); clearChildren(); } /** Returns the first actor found with the specified name. Note this recursively compares the name of every actor in the group. */ public Actor3d findActor (String name) { Array<Actor3d> children = this.children; for (int i = 0, n = children.size; i < n; i++) if (name.equals(children.get(i).getName())) return children.get(i); for (int i = 0, n = children.size; i < n; i++) { Actor3d child = children.get(i); if (child instanceof Group3d) { Actor3d actor = ((Group3d)child).findActor(name); if (actor != null) return actor; } } return null; } @Override protected void setStage3d (Stage3d stage3d) { super.setStage3d(stage3d); Array<Actor3d> children = this.children; for (int i = 0, n = children.size; i < n; i++) children.get(i).setStage3d(stage3d); } /** Returns an ordered list of child actors in this group. */ public SnapshotArray<Actor3d> getChildren () { return children; } public boolean hasChildren () { return children.size > 0; } /** Prints the actor hierarchy recursively for debugging purposes. */ public void print () { print(""); } private void print (String indent) { Actor3d[] actors = children.begin(); for (int i = 0, n = children.size; i < n; i++) { System.out.println(indent + actors[i]); if (actors[i] instanceof Group3d) ((Group3d)actors[i]).print(indent + "| "); } children.end(); } @Override public void dispose() { super.dispose(); for(Actor3d actor3d: children) actor3d.dispose(); } }