use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.
the class GeometryBatchFactory method alignBuffers.
/**
* Will ensure that all the geometries' meshes of the n sub graph have the
* same types of buffers
* @param n the node to gather geometries from
* @param option the align options
* @see AlignOption
*
* Very experimental for now.
*/
public static void alignBuffers(Node n, AlignOption option) {
List<Geometry> geoms = new ArrayList<Geometry>();
gatherGeoms(n, geoms);
//gather buffer types
Map<VertexBuffer.Type, VertexBuffer> types = new EnumMap<VertexBuffer.Type, VertexBuffer>(VertexBuffer.Type.class);
Map<VertexBuffer.Type, Integer> typesCount = new EnumMap<VertexBuffer.Type, Integer>(VertexBuffer.Type.class);
for (Geometry geom : geoms) {
for (VertexBuffer buffer : geom.getMesh().getBufferList()) {
if (types.get(buffer.getBufferType()) == null) {
types.put(buffer.getBufferType(), buffer);
logger.log(Level.FINE, buffer.getBufferType().toString());
}
Integer count = typesCount.get(buffer.getBufferType());
if (count == null) {
count = 0;
}
count++;
typesCount.put(buffer.getBufferType(), count);
}
}
switch(option) {
case RemoveUnalignedBuffers:
for (Geometry geom : geoms) {
for (VertexBuffer buffer : geom.getMesh().getBufferList()) {
Integer count = typesCount.get(buffer.getBufferType());
if (count != null && count < geoms.size()) {
geom.getMesh().clearBuffer(buffer.getBufferType());
logger.log(Level.FINE, "removing {0} from {1}", new Object[] { buffer.getBufferType(), geom.getName() });
}
}
}
break;
case CreateMissingBuffers:
for (Geometry geom : geoms) {
for (VertexBuffer.Type type : types.keySet()) {
if (geom.getMesh().getBuffer(type) == null) {
VertexBuffer vb = new VertexBuffer(type);
Buffer b;
switch(type) {
case Index:
case BoneIndex:
case HWBoneIndex:
b = BufferUtils.createIntBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
break;
case InterleavedData:
b = BufferUtils.createByteBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
break;
default:
b = BufferUtils.createFloatBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
}
vb.setupData(types.get(type).getUsage(), types.get(type).getNumComponents(), types.get(type).getFormat(), b);
geom.getMesh().setBuffer(vb);
logger.log(Level.FINE, "geom {0} misses buffer {1}. Creating", new Object[] { geom.getName(), type });
}
}
}
break;
}
}
use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.
the class TextureAtlas method createAtlas.
/**
* Create a texture atlas for the given root node, containing DiffuseMap, NormalMap and SpecularMap.
* @param root The rootNode to create the atlas for.
* @param atlasSize The size of the atlas (width and height).
* @return Null if the atlas cannot be created because not all textures fit.
*/
public static TextureAtlas createAtlas(Spatial root, int atlasSize) {
List<Geometry> geometries = new ArrayList<Geometry>();
GeometryBatchFactory.gatherGeoms(root, geometries);
TextureAtlas atlas = new TextureAtlas(atlasSize, atlasSize);
for (Geometry geometry : geometries) {
if (!atlas.addGeometry(geometry)) {
logger.log(Level.WARNING, "Texture atlas size too small, cannot add all textures");
return null;
}
}
return atlas;
}
use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.
the class LightSortTest method testSceneGraphSort.
@Test
public void testSceneGraphSort() {
Node n = new Node("node");
Geometry g = new Geometry("geom", new Mesh());
SpotLight spot = new SpotLight(Vector3f.ZERO, Vector3f.UNIT_X);
PointLight point = new PointLight(Vector3f.UNIT_X);
DirectionalLight directional = new DirectionalLight(Vector3f.UNIT_X);
AmbientLight ambient = new AmbientLight();
// Some lights are on the node
n.addLight(spot);
n.addLight(point);
// .. and some on the geometry.
g.addLight(directional);
g.addLight(ambient);
n.attachChild(g);
n.updateGeometricState();
LightList list = g.getWorldLightList();
// check the sorting (when geom is at 0,0,0)
assert list.get(0) instanceof AmbientLight;
assert list.get(1) instanceof DirectionalLight;
assert list.get(2) instanceof SpotLight;
assert list.get(3) instanceof PointLight;
// move the geometry closer to the point light
g.setLocalTranslation(Vector3f.UNIT_X);
n.updateGeometricState();
assert list.get(0) instanceof AmbientLight;
assert list.get(1) instanceof DirectionalLight;
assert list.get(2) instanceof PointLight;
assert list.get(3) instanceof SpotLight;
// now move the point light away from the geometry
// and the spot light closer
// XXX: doesn't work! jME can't detect that the light moved!
// point.setPosition(Vector3f.ZERO);
// spot.setPosition(Vector3f.UNIT_X);
// n.updateGeometricState();
//
// assert list.get(0) instanceof AmbientLight;
// assert list.get(1) instanceof DirectionalLight;
// assert list.get(2) instanceof SpotLight;
// assert list.get(3) instanceof PointLight;
}
use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.
the class FbxBindPose method fromElement.
@Override
public void fromElement(FbxElement element) {
super.fromElement(element);
for (FbxElement child : element.children) {
if (!child.id.equals("PoseNode")) {
continue;
}
FbxId node = null;
float[] matData = null;
for (FbxElement e : child.children) {
if (e.id.equals("Node")) {
node = FbxId.create(e.properties.get(0));
} else if (e.id.equals("Matrix")) {
double[] matDataDoubles = (double[]) e.properties.get(0);
if (matDataDoubles.length != 16) {
// corrupt
throw new UnsupportedOperationException("Bind pose matrix " + "must have 16 doubles, but it has " + matDataDoubles.length + ". Data is corrupt");
}
matData = new float[16];
for (int i = 0; i < matDataDoubles.length; i++) {
matData[i] = (float) matDataDoubles[i];
}
}
}
if (node != null && matData != null) {
Matrix4f matrix = new Matrix4f(matData);
bindPose.put(node, matrix);
}
}
}
use of com.jme3.scene.Node in project jmonkeyengine by jMonkeyEngine.
the class FbxLoader method constructAnimations.
private void constructAnimations() {
// In FBX, animation are not attached to any root.
// They are implicitly global.
// So, we need to use hueristics to find which node(s)
// an animation is associated with, so we can create the AnimControl
// in the appropriate location in the scene.
Map<FbxToJmeTrack, FbxToJmeTrack> pairs = new HashMap<FbxToJmeTrack, FbxToJmeTrack>();
for (FbxAnimStack stack : animStacks) {
for (FbxAnimLayer layer : stack.getLayers()) {
for (FbxAnimCurveNode curveNode : layer.getAnimationCurveNodes()) {
for (Map.Entry<FbxNode, String> nodePropertyEntry : curveNode.getInfluencedNodeProperties().entrySet()) {
FbxToJmeTrack lookupPair = new FbxToJmeTrack();
lookupPair.animStack = stack;
lookupPair.animLayer = layer;
lookupPair.node = nodePropertyEntry.getKey();
// Find if this pair is already stored
FbxToJmeTrack storedPair = pairs.get(lookupPair);
if (storedPair == null) {
// If not, store it.
storedPair = lookupPair;
pairs.put(storedPair, storedPair);
}
String property = nodePropertyEntry.getValue();
storedPair.animCurves.put(property, curveNode);
}
}
}
}
// At this point we can construct the animation for all pairs ...
for (FbxToJmeTrack pair : pairs.values()) {
String animName = pair.animStack.getName();
float duration = pair.animStack.getDuration();
System.out.println("ANIMATION: " + animName + ", duration = " + duration);
System.out.println("NODE: " + pair.node.getName());
duration = pair.getDuration();
if (pair.node instanceof FbxLimbNode) {
// Find the spatial that has the skeleton for this limb.
FbxLimbNode limbNode = (FbxLimbNode) pair.node;
Bone bone = limbNode.getJmeBone();
Spatial jmeSpatial = limbNode.getSkeletonHolder().getJmeObject();
Skeleton skeleton = limbNode.getSkeletonHolder().getJmeSkeleton();
// Get the animation control (create if missing).
AnimControl animControl = jmeSpatial.getControl(AnimControl.class);
if (animControl.getSkeleton() != skeleton) {
throw new UnsupportedOperationException();
}
// Get the animation (create if missing).
Animation anim = animControl.getAnim(animName);
if (anim == null) {
anim = new Animation(animName, duration);
animControl.addAnim(anim);
}
// Find the bone index from the spatial's skeleton.
int boneIndex = skeleton.getBoneIndex(bone);
// Generate the bone track.
BoneTrack bt = pair.toJmeBoneTrack(boneIndex, bone.getBindInverseTransform());
// Add the bone track to the animation.
anim.addTrack(bt);
} else {
// Create the spatial animation
Animation anim = new Animation(animName, duration);
anim.setTracks(new Track[] { pair.toJmeSpatialTrack() });
// Get the animation control (create if missing).
Spatial jmeSpatial = pair.node.getJmeObject();
AnimControl animControl = jmeSpatial.getControl(AnimControl.class);
if (animControl == null) {
animControl = new AnimControl(null);
jmeSpatial.addControl(animControl);
}
// Add the spatial animation
animControl.addAnim(anim);
}
}
}
Aggregations