[opensource-dev] Review Request: BUG-840: Viewer 3.4.2 (Beta) breaks almost every sliding door script in SL

Henri Beauchamp sldev at free.fr
Fri Feb 15 02:51:57 PST 2013


On Fri, 15 Feb 2013 09:54:16 -0000, MartinRJ Fayray wrote:

I have a similar fix for weeks in the Cool VL Viewer, but it is alas
not as simple as that...

There's a problem with resizing chid primitives (they don't resize
on screen, even when visible).
There's a problem with rotating and moving child primitives when
they are out of FOV, but fixing it by checking for target rot and
position changes like you did also breaks *some* vehicles (when you
or another avatar sits on such vehicles, some chil primitives
pertaining to this vehicle "stay behind" when the vehicle moves).

So, far, I came up with a proper fix for resizing child primitives
and an experimental fix for moving/rotating out of FOV child
primitives (I'm testing for flagUsePhysics() and not applying the
fix when the flag is TRUE, which should exclude vehicles cild prims).
By lack of vehicles to test the latter (I don't use vehicles in SL
and the couple I got in my inventory are not affected by this bug),
I cannot guarantee that it is "final".

Here is the code I use, for people interested in experiencing:

// Returns "distance" between target destination and resulting xfrom
F32 LLDrawable::updateXform(BOOL undamped)
{
	BOOL damped = !undamped;

	// Position
	LLVector3 old_pos(mXform.getPosition());
	LLVector3 target_pos;
	if (mXform.isRoot())
	{
		// get root position in your agent's region
		target_pos = mVObjp->getPositionAgent();
	}
	else
	{
		// parent-relative position
		target_pos = mVObjp->getPosition();
	}

	// Rotation
	LLQuaternion old_rot(mXform.getRotation());
	LLQuaternion target_rot = mVObjp->getRotation();
	bool no_target_omega = mVObjp->getAngularVelocity().isExactlyZero();

	// Scaling
	LLVector3 target_scale = mVObjp->getScale();
	LLVector3 old_scale = mCurrentScale;
	LLVector3 dest_scale = target_scale;

	// Damping
	F32 dist_squared = 0.f;
	F32 camdist2 = mDistanceWRTCamera * mDistanceWRTCamera;

	if (damped && isVisible())
	{
		F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT),
															  0.f, 1.f);
		LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);
		dist_squared = dist_vec_squared(new_pos, target_pos);

		LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot);
		dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f;

		LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt);
		dist_squared += dist_vec_squared(new_scale, target_scale);

		if (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2 &&
			dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)
		{
			// interpolate
			target_pos = new_pos;
			target_rot = new_rot;
			target_scale = new_scale;
		}
		else if (no_target_omega)
		{
			// snap to final position (only if no target omega is applied)
			dist_squared = 0.0f;
			if (getVOVolume() && !isRoot())
			{	// child prim snapping to some position, needs a rebuild
				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION,
									  TRUE);
			}
		}
	}

	if (old_scale != target_scale)
	{	// scale change requires immediate rebuild
		mCurrentScale = target_scale;
		if (!isRoot() && !isState(LLDrawable::ANIMATED_CHILD))
		{
			setState(LLDrawable::ANIMATED_CHILD);
			mVObjp->dirtySpatialGroup();
		}
		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
	}
	else if (!isRoot() && !mVObjp->getRootEdit()->flagUsePhysics() &&
			 (dist_squared > 0.f || old_pos != target_pos ||
			  target_rot != old_rot || !no_target_omega))
	{
		// child prim moving relative to parent, tag as needing to be rendered
		// atomically and rebuild
		dist_squared = 1.f; // keep this object on the move list
		if (!isState(LLDrawable::ANIMATED_CHILD))
		{
			setState(LLDrawable::ANIMATED_CHILD);
			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
			mVObjp->dirtySpatialGroup();
		}
	}
	else if (!getVOVolume() && !isAvatar())
	{
		movePartition();
	}

	// Update
	mXform.setPosition(target_pos);
	mXform.setRotation(target_rot);
	mXform.setScale(LLVector3(1, 1, 1)); // no scale in drawable transforms (IT'S A RULE!)
	mXform.updateMatrix();

	if (mSpatialBridge)
	{
		gPipeline.markMoved(mSpatialBridge, FALSE);
	}

	return dist_squared;
}

Henri.


More information about the opensource-dev mailing list