Lights (see #362) : added light v. sphere intersection, and implementations of intersectsSphere(), second attempt

experimental
Dokthar 9 years ago
parent 3412c0cf2b
commit cfdb9a8759
  1. 6
      jme3-core/src/main/java/com/jme3/light/AmbientLight.java
  2. 7
      jme3-core/src/main/java/com/jme3/light/DefaultLightFilter.java
  3. 6
      jme3-core/src/main/java/com/jme3/light/DirectionalLight.java
  4. 15
      jme3-core/src/main/java/com/jme3/light/Light.java
  5. 12
      jme3-core/src/main/java/com/jme3/light/PointLight.java
  6. 42
      jme3-core/src/main/java/com/jme3/light/SpotLight.java

@ -32,6 +32,7 @@
package com.jme3.light;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
@ -62,6 +63,11 @@ public class AmbientLight extends Light {
return true;
}
@Override
public boolean intersectsSphere(BoundingSphere sphere, TempVars vars) {
return true;
}
@Override
public boolean intersectsFrustum(Camera camera, TempVars vars) {
return true;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2014 jMonkeyEngine
* Copyright (c) 2009-2015 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -78,8 +78,9 @@ public final class DefaultLightFilter implements LightFilter {
}
} else if (bv instanceof BoundingSphere) {
if (!Float.isInfinite( ((BoundingSphere)bv).getRadius() )) {
// Non-infinite bounding sphere... Not supported yet.
throw new UnsupportedOperationException("Only AABB supported for now");
if (!light.intersectsSphere((BoundingSphere)bv, vars)) {
continue;
}
}
}

@ -32,6 +32,7 @@
package com.jme3.light;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
@ -116,6 +117,11 @@ public class DirectionalLight extends Light {
return true;
}
@Override
public boolean intersectsSphere(BoundingSphere sphere, TempVars vars) {
return true;
}
@Override
public boolean intersectsFrustum(Camera camera, TempVars vars) {
return true;

@ -32,6 +32,7 @@
package com.jme3.light;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.export.*;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.Camera;
@ -196,6 +197,20 @@ public abstract class Light implements Savable, Cloneable {
*/
public abstract boolean intersectsBox(BoundingBox box, TempVars vars);
/**
* Determines if the light intersects with the given bounding sphere.
* <p>
* For non-local lights, such as {@link DirectionalLight directional lights},
* {@link AmbientLight ambient lights}, or {@link PointLight point lights}
* without influence radius, this method should always return true.
*
* @param sphere The sphere to check intersection against.
* @param vars TempVars in case it is needed.
*
* @return True if the light intersects the sphere, false otherwise.
*/
public abstract boolean intersectsSphere(BoundingSphere sphere, TempVars vars);
/**
* Determines if the light intersects with the given camera frustum.
*

@ -32,12 +32,14 @@
package com.jme3.light;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.bounding.BoundingVolume;
import com.jme3.bounding.Intersection;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
@ -195,6 +197,16 @@ public class PointLight extends Light {
}
}
@Override
public boolean intersectsSphere(BoundingSphere sphere, TempVars vars) {
if (this.radius == 0) {
return true;
} else {
// Sphere v. sphere collision
return sphere.getCenter().subtract(position).lengthSquared() < FastMath.sqr(radius + sphere.getRadius());
}
}
@Override
public boolean intersectsFrustum(Camera camera, TempVars vars) {
if (this.radius == 0) {

@ -32,6 +32,7 @@
package com.jme3.light;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.bounding.BoundingVolume;
import com.jme3.export.*;
import com.jme3.math.ColorRGBA;
@ -225,12 +226,49 @@ public class SpotLight extends Light {
return false;
}
@Override
public boolean intersectsSphere(BoundingSphere sphere, TempVars vars) {
if (this.spotRange > 0f) {
// Check spot range first.
// Sphere v. sphere collision
if (sphere.getCenter().subtract(position).lengthSquared() >= FastMath.sqr(spotRange + sphere.getRadius())) {
return false;
}
}
float otherRadiusSquared = FastMath.sqr(sphere.getRadius());
float otherRadius = sphere.getRadius();
// Check if sphere is within spot angle.
// Cone v. sphere collision.
Vector3f E = direction.mult(otherRadius * outerAngleSinRcp, vars.vect1);
Vector3f U = position.subtract(E, vars.vect2);
Vector3f D = sphere.getCenter().subtract(U, vars.vect3);
float dsqr = D.dot(D);
float e = direction.dot(D);
if (e > 0f && e * e >= dsqr * outerAngleCosSqr) {
D = sphere.getCenter().subtract(position, vars.vect3);
dsqr = D.dot(D);
e = -direction.dot(D);
if (e > 0f && e * e >= dsqr * outerAngleSinSqr) {
return dsqr <= otherRadiusSquared;
} else {
return true;
}
}
return false;
}
@Override
public boolean intersectsFrustum(Camera cam, TempVars vars) {
if (spotRange == 0) {
// The algorithm below does not support infinite spot range.
return true;
}
return true;
}
Vector3f farPoint = vars.vect1.set(position).addLocal(vars.vect2.set(direction).multLocal(spotRange));
for (int i = 5; i >= 0; i--) {
//check origin against the plane

Loading…
Cancel
Save