use of com.jme3.scene.plugins.blender.meshes.Point 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.plugins.blender.meshes.Point 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);
}
}
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class ObjectHelper method isParent.
/**
* Checks if the first given OMA points to a parent of the second one.
* The parent need not to be the direct one. This method should be called when we are sure
* that both of the features are alred loaded because it does not check it.
* The OMA's should point to a spatials, otherwise the function will throw ClassCastException.
* @param supposedParentOMA
* the OMA of the node that we suppose might be a parent of the second one
* @param spatialOMA
* the OMA of the scene's node
* @return <b>true</b> if the first given OMA points to a parent of the second one and <b>false</b> otherwise
*/
public boolean isParent(Long supposedParentOMA, Long spatialOMA) {
Spatial supposedParent = (Spatial) blenderContext.getLoadedFeature(supposedParentOMA, LoadedDataType.FEATURE);
Spatial spatial = (Spatial) blenderContext.getLoadedFeature(spatialOMA, LoadedDataType.FEATURE);
Spatial parent = spatial.getParent();
while (parent != null) {
if (parent.equals(supposedParent)) {
return true;
}
parent = parent.getParent();
}
return false;
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class ParticlesHelper method toParticleEmitter.
@SuppressWarnings("unchecked")
public ParticleEmitter toParticleEmitter(Structure particleSystem) throws BlenderFileException {
ParticleEmitter result = null;
Pointer pParticleSettings = (Pointer) particleSystem.getFieldValue("part");
if (pParticleSettings.isNotNull()) {
Structure particleSettings = pParticleSettings.fetchData().get(0);
int totPart = ((Number) particleSettings.getFieldValue("totpart")).intValue();
// draw type will be stored temporarily in the name (it is used during modifier applying operation)
int drawAs = ((Number) particleSettings.getFieldValue("draw_as")).intValue();
// P - point, L - line, N - None, B - Bilboard
char nameSuffix;
switch(drawAs) {
case PART_DRAW_NOT:
nameSuffix = 'N';
// no need to generate particles in this case
totPart = 0;
break;
case PART_DRAW_BB:
nameSuffix = 'B';
break;
case PART_DRAW_OB:
case PART_DRAW_GR:
nameSuffix = 'P';
// TODO: support groups and aobjects
LOGGER.warning("Neither object nor group particles supported yet! Using point representation instead!");
break;
case PART_DRAW_LINE:
nameSuffix = 'L';
// TODO: support lines
LOGGER.warning("Lines not yet supported! Using point representation instead!");
default:
// all others are rendered as points in blender
nameSuffix = 'P';
}
result = new ParticleEmitter(particleSettings.getName() + nameSuffix, Type.Triangle, totPart);
if (nameSuffix == 'N') {
// no need to set anything else
return result;
}
// setting the emitters shape (the shapes meshes will be set later during modifier applying operation)
int from = ((Number) particleSettings.getFieldValue("from")).intValue();
switch(from) {
case PART_FROM_VERT:
result.setShape(new EmitterMeshVertexShape());
break;
case PART_FROM_FACE:
result.setShape(new EmitterMeshFaceShape());
break;
case PART_FROM_VOLUME:
result.setShape(new EmitterMeshConvexHullShape());
break;
default:
LOGGER.warning("Default shape used! Unknown emitter shape value ('from' parameter: " + from + ')');
}
// reading acceleration
DynamicArray<Number> acc = (DynamicArray<Number>) particleSettings.getFieldValue("acc");
result.setGravity(-acc.get(0).floatValue(), -acc.get(1).floatValue(), -acc.get(2).floatValue());
// setting the colors
result.setEndColor(new ColorRGBA(1f, 1f, 1f, 1f));
result.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f));
// reading size
float sizeFactor = nameSuffix == 'B' ? 1.0f : 0.3f;
float size = ((Number) particleSettings.getFieldValue("size")).floatValue() * sizeFactor;
result.setStartSize(size);
result.setEndSize(size);
// reading lifetime
int fps = blenderContext.getBlenderKey().getFps();
float lifetime = ((Number) particleSettings.getFieldValue("lifetime")).floatValue() / fps;
float randlife = ((Number) particleSettings.getFieldValue("randlife")).floatValue() / fps;
result.setLowLife(lifetime * (1.0f - randlife));
result.setHighLife(lifetime);
// preparing influencer
ParticleInfluencer influencer;
int phystype = ((Number) particleSettings.getFieldValue("phystype")).intValue();
switch(phystype) {
case PART_PHYS_NEWTON:
influencer = new NewtonianParticleInfluencer();
((NewtonianParticleInfluencer) influencer).setNormalVelocity(((Number) particleSettings.getFieldValue("normfac")).floatValue());
((NewtonianParticleInfluencer) influencer).setVelocityVariation(((Number) particleSettings.getFieldValue("randfac")).floatValue());
((NewtonianParticleInfluencer) influencer).setSurfaceTangentFactor(((Number) particleSettings.getFieldValue("tanfac")).floatValue());
((NewtonianParticleInfluencer) influencer).setSurfaceTangentRotation(((Number) particleSettings.getFieldValue("tanphase")).floatValue());
break;
case PART_PHYS_BOIDS:
case // TODO: support other influencers
PART_PHYS_KEYED:
LOGGER.warning("Boids and Keyed particles physic not yet supported! Empty influencer used!");
case PART_PHYS_NO:
default:
influencer = new EmptyParticleInfluencer();
}
result.setParticleInfluencer(influencer);
}
return result;
}
use of com.jme3.scene.plugins.blender.meshes.Point in project jmonkeyengine by jMonkeyEngine.
the class Edge method getCrossPoint.
/**
* The method computes the crossing pint of this edge and another edge. If
* there is no crossing then null is returned. Also null is returned if the edges are parallel.
* This method also allows to get the crossing point of the straight lines that contain these edges if
* you set the 'extend' parameter to true.
*
* @param edge
* the edge to compute corss point with
* @param extendThisEdge
* set to <b>true</b> to find a crossing point along the whole
* straight that contains the current edge
* @param extendSecondEdge
* set to <b>true</b> to find a crossing point along the whole
* straight that contains the given edge
* @return cross point on null if none exist or the edges are parallel
*/
public Vector3f getCrossPoint(Edge edge, boolean extendThisEdge, boolean extendSecondEdge) {
Vector3d P1 = new Vector3d(this.getFirstVertex());
Vector3d P2 = new Vector3d(edge.getFirstVertex());
Vector3d u = new Vector3d(this.getSecondVertex()).subtract(P1).normalizeLocal();
Vector3d v = new Vector3d(edge.getSecondVertex()).subtract(P2).normalizeLocal();
if (Math.abs(u.dot(v)) >= 1 - FastMath.DBL_EPSILON) {
// the edges are parallel; do not care about the crossing point
return null;
}
double t1 = 0, t2 = 0;
if (u.x == 0 && v.x == 0) {
t2 = (u.z * (P2.y - P1.y) - u.y * (P2.z - P1.z)) / (u.y * v.z - u.z * v.y);
t1 = (P2.z - P1.z + v.z * t2) / u.z;
} else if (u.y == 0 && v.y == 0) {
t2 = (u.x * (P2.z - P1.z) - u.z * (P2.x - P1.x)) / (u.z * v.x - u.x * v.z);
t1 = (P2.x - P1.x + v.x * t2) / u.x;
} else if (u.z == 0 && v.z == 0) {
t2 = (u.x * (P2.y - P1.y) - u.y * (P2.x - P1.x)) / (u.y * v.x - u.x * v.y);
t1 = (P2.x - P1.x + v.x * t2) / u.x;
} else {
t2 = (P1.y * u.x - P1.x * u.y + P2.x * u.y - P2.y * u.x) / (v.y * u.x - u.y * v.x);
t1 = (P2.x - P1.x + v.x * t2) / u.x;
if (Math.abs(P1.z - P2.z + u.z * t1 - v.z * t2) > FastMath.FLT_EPSILON) {
return null;
}
}
Vector3d p1 = P1.add(u.mult(t1));
Vector3d p2 = P2.add(v.mult(t2));
if (p1.distance(p2) <= FastMath.FLT_EPSILON) {
if (extendThisEdge && extendSecondEdge) {
return p1.toVector3f();
}
// the lines cross, check if p1 and p2 are within the edges
Vector3d p = p1.subtract(P1);
double cos = p.dot(u) / p.length();
if (extendThisEdge || p.length() <= FastMath.FLT_EPSILON || cos >= 1 - FastMath.FLT_EPSILON && p.length() - this.getLength() <= FastMath.FLT_EPSILON) {
// p1 is inside the first edge, lets check the other edge now
p = p2.subtract(P2);
cos = p.dot(v) / p.length();
if (extendSecondEdge || p.length() <= FastMath.FLT_EPSILON || cos >= 1 - FastMath.FLT_EPSILON && p.length() - edge.getLength() <= FastMath.FLT_EPSILON) {
return p1.toVector3f();
}
}
}
return null;
}
Aggregations