|
|
|
@ -35,6 +35,7 @@ import com.jme3.bounding.BoundingBox; |
|
|
|
|
import com.jme3.bounding.BoundingVolume; |
|
|
|
|
import com.jme3.export.*; |
|
|
|
|
import com.jme3.math.FastMath; |
|
|
|
|
import com.jme3.math.Plane; |
|
|
|
|
import com.jme3.math.Vector3f; |
|
|
|
|
import com.jme3.renderer.Camera; |
|
|
|
|
import com.jme3.scene.Spatial; |
|
|
|
@ -66,7 +67,7 @@ public class SpotLight extends Light implements Savable { |
|
|
|
|
protected float packedAngleCos=0; |
|
|
|
|
|
|
|
|
|
protected float outerAngleCosSqr, outerAngleSinSqr; |
|
|
|
|
protected float outerAngleSinRcp; |
|
|
|
|
protected float outerAngleSinRcp, outerAngleSin; |
|
|
|
|
|
|
|
|
|
public SpotLight() { |
|
|
|
|
super(); |
|
|
|
@ -90,10 +91,10 @@ public class SpotLight extends Light implements Savable { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// compute parameters needed for cone vs sphere check.
|
|
|
|
|
float outerSin = FastMath.sin(spotOuterAngle); |
|
|
|
|
outerAngleSin = FastMath.sin(spotOuterAngle); |
|
|
|
|
outerAngleCosSqr = outerCos * outerCos; |
|
|
|
|
outerAngleSinSqr = outerSin * outerSin; |
|
|
|
|
outerAngleSinRcp = 1.0f / outerSin; |
|
|
|
|
outerAngleSinSqr = outerAngleSin * outerAngleSin; |
|
|
|
|
outerAngleSinRcp = 1.0f / outerAngleSin; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@ -143,9 +144,29 @@ public class SpotLight extends Light implements Savable { |
|
|
|
|
if (this.spotRange == 0) { |
|
|
|
|
return true; |
|
|
|
|
} else { |
|
|
|
|
// Do a frustum v. sphere test against the spot range.
|
|
|
|
|
// Do a frustum v. OBB test.
|
|
|
|
|
|
|
|
|
|
// Determine OBB extents assuming OBB center is the middle
|
|
|
|
|
// point between the cone's vertex and its range.
|
|
|
|
|
float sideExtent = spotRange * 0.5f * outerAngleSin; |
|
|
|
|
float forwardExtent = spotRange * 0.5f; |
|
|
|
|
|
|
|
|
|
// Create OBB axes via direction and Y up vector.
|
|
|
|
|
Vector3f xAxis = Vector3f.UNIT_Y.cross(direction, vars.vect1).normalizeLocal(); |
|
|
|
|
Vector3f yAxis = direction.cross(xAxis, vars.vect2).normalizeLocal(); |
|
|
|
|
Vector3f obbCenter = direction.mult(spotRange * 0.5f, vars.vect3).addLocal(position); |
|
|
|
|
|
|
|
|
|
for (int i = 5; i >= 0; i--) { |
|
|
|
|
if (camera.getWorldPlane(i).pseudoDistance(position) <= -spotRange) { |
|
|
|
|
Plane plane = camera.getWorldPlane(i); |
|
|
|
|
Vector3f planeNormal = plane.getNormal(); |
|
|
|
|
|
|
|
|
|
// OBB v. plane intersection
|
|
|
|
|
float radius = FastMath.abs(sideExtent * (planeNormal.dot(xAxis))) |
|
|
|
|
+ FastMath.abs(sideExtent * (planeNormal.dot(yAxis))) |
|
|
|
|
+ FastMath.abs(forwardExtent * (planeNormal.dot(direction))); |
|
|
|
|
|
|
|
|
|
float distance = plane.pseudoDistance(obbCenter); |
|
|
|
|
if (distance <= -radius) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|