Or, a total misunderstanding on my part… I’m willing to accept either.

In my quest to find my missing frames with the upgrade (hint: this isn’t it but worth looking at), I ran across some code that made me scratch my head.

Current code:

[java]

public float distanceToCam(Geometry spat){

if (spat == null)

return Float.NEGATIVE_INFINITY;

if (spat.queueDistance != Float.NEGATIVE_INFINITY)

return spat.queueDistance;

Vector3f camPosition = cam.getLocation();

Vector3f viewVector = cam.getDirection();

Vector3f spatPosition = null;

if (spat.getWorldBound() != null){

spatPosition = spat.getWorldBound().getCenter();

}else{

spatPosition = spat.getWorldTranslation();

}

spatPosition.subtract(camPosition, tempVec);

spat.queueDistance = tempVec.dot(tempVec);

float retval = Math.abs(tempVec.dot(viewVector)

/ viewVector.dot(viewVector));

viewVector.mult(retval, tempVec);

spat.queueDistance = tempVec.length();

return spat.queueDistance;

}

[/java]

Now, no one will tell you that my vector algebra is weaker than I will but some things in there tripped me up at first. When I saw the thrown away, no-side-effect apparent that I can see, initial setting of queueDistance, I began to wonder if this might be the ‘code of many patches’. So I looked deeper and had some questions in case my understanding is faulty.

- Is their ever a case where viewVector is not a vector of length 1?

- Is queueDistance ever used for anything other than sorting the opaque bin? (I can’t find anywhere that it is doing a grep through the source code.)

In my understanding, dotting a vector with itself, as in:

[java]viewVector.dot(viewVector)[/java]

At worst, will give you the squared length and of course, at best, if viewVector is unit then you get 1.

At any rate, presuming that queue distance is only used for sorting then it really shouldn’t matter how long viewVector is. A dot() of tempVec and viewVector is enough to determine relative distance and if viewVector is unit then it is also*actual*distance. Again, presuming my math is right. I’ve been hit over the head with a text book more than once in these kinds of conversations.

Given all of that, I believe the method can be shortened to:

[java]

public float distanceToCam(Geometry spat){

if (spat == null)

return Float.NEGATIVE_INFINITY;

if (spat.queueDistance != Float.NEGATIVE_INFINITY)

return spat.queueDistance;

Vector3f camPosition = cam.getLocation();

Vector3f viewVector = cam.getDirection();

Vector3f spatPosition = null;

if (spat.getWorldBound() != null){

spatPosition = spat.getWorldBound().getCenter();

}else{

spatPosition = spat.getWorldTranslation();

}

spatPosition.subtract(camPosition, tempVec);

spat.queueDistance = tempVec.dot(viewVector);

return spat.queueDistance;

}

[/java]

In my scene where the stats report that I have 400 objects, this takes me from ~73 FPS to around 80 FPS. The lack of a sqrt call is probably the biggest of the savings but the other removed calls can’t hurt.

Unfortunately, similar logic cannot be applied to the transparent comparator as it stands since it uses the distanceToEdge() call which always does a sqrt. (no real choice there presuming the near edge is really the better sort criteria.)