Esempio n. 1
0
//----------------------------------------------------------------------------
void CurveCtrlFloat::OnCtrlChanged (bool updateCurve)
{
    if (mIndex >= (int)(mCurveFloat->mCurve->Points.size()))
        return;

    float inVal = mCurveFloat->mCurve->Points[mIndex].InVal;
    float outVal = mCurveFloat->mCurve->Points[mIndex].OutVal;
    float arriveTangent = mCurveFloat->mCurve->Points[mIndex].ArriveTangent;
    float leaveTangent = mCurveFloat->mCurve->Points[mIndex].LeaveTangent;
    InterpCurveMode mode = mCurveFloat->mCurve->Points[mIndex].InterpMode;

    mInVal = inVal;
    mOutVal = Float3(inVal, 0.0f, outVal);

    AVector at(1.0f, 0.0f, arriveTangent);
    at.Normalize();
    mArriveTangent = at;

    AVector lt (1.0f, 0.0f, leaveTangent);
    lt.Normalize();
    mLeaveTangent = lt;

    mInterpCurveMode = mode;

    CurveCtrl::OnCtrlChanged(updateCurve);
}
Esempio n. 2
0
//----------------------------------------------------------------------------
AVector SteeringBehavior::Flee (APoint fromPosition)
{
	AVector desiredVelocity = mActor->GetPosition() - fromPosition;
	desiredVelocity.Normalize();

	return (desiredVelocity - mActor->GetVelocity());
}
//----------------------------------------------------------------------------
bool InputPushTransformController::IsSmallTransScope()
{
	AVector smallScope = mMaxPosSmall - mMinPosSmall;
	float lengthSquare = smallScope.SquaredLength();

	return 0.0f != lengthSquare;
}
Esempio n. 4
0
//----------------------------------------------------------------------------
void SceneNodeCtrl::OnMouseWheel(RenderStep *renderStep, float wheelDelta)
{
	Camera *camera = renderStep->GetCamera();
	float rmax = camera->GetRMax();
	APoint camPosition = camera->GetPosition();
	APoint ctrlPosition = GetPosition();
	AVector diff = ctrlPosition - camPosition;
	float diffLength = diff.Length();

	if (mLookType != LT_PERSPECTIVE)
	{
		if (0.0f != rmax)
		{
			mCtrlsGroup->WorldTransform.SetUniformScale(rmax*0.11f);
			mCtrlsGroup->Update(Time::GetTimeInSeconds(), false);
		}
	}
	else
	{
		float scale = diffLength*0.04f;
		if (scale == 0.0f) scale = 0.0001f;
		if (scale < 1.0f) scale = 1.0f;
		mCtrlsGroup->WorldTransform.SetUniformScale(scale);
		mCtrlsGroup->Update(Time::GetTimeInSeconds(), false);
	}
}
Esempio n. 5
0
//----------------------------------------------------------------------------
void ClodMeshes::UpdateClods ()
{
    // Adjust the triangle quantities for the clod meshes.  The distance along
    // the camera direction controls the triangle quantities.  A nonlinear
    // drop-off is used.
    for (int i = 0; i < 2; ++i)
    {
        AVector diff =
            mClod[i]->WorldBound.GetCenter() - mCamera->GetPosition();

        float depth = diff.Dot(mCamera->GetDVector());
        int targetRecord;
        if (depth <= mCamera->GetDMin())
        {
            targetRecord = 0;
        }
        else if (depth >= mCamera->GetDMax())
        {
            targetRecord = mClod[i]->GetNumRecords() - 1;
        }
        else
        {
            float dmin = mCamera->GetDMin();
            float dmax = mCamera->GetDMax();
            float ratio = Mathf::Pow((depth - dmin)/(dmax - dmin), 0.5f);
            targetRecord = (int)((mClod[i]->GetNumRecords() - 1)*ratio);
        }

        mClod[i]->TargetRecord() = targetRecord;
    }
}
Esempio n. 6
0
//----------------------------------------------------------------------------
bool Bound::TestIntersection (const Bound& bound, float tmax,
							  const AVector& velocity0, const AVector& velocity1) const
{
	if (bound.GetRadius() == 0.0f || GetRadius() == 0.0f)
	{
		return false;
	}

	AVector relVelocity = velocity1 - velocity0; // 相对速度
	AVector cenDiff = bound.mCenter - mCenter; // 相对位移
	float a = relVelocity.SquaredLength();
	float c = cenDiff.SquaredLength();
	float rSum = bound.mRadius + mRadius;
	float rSumSqr = rSum*rSum;

	if (a > 0.0f)
	{
		float b = cenDiff.Dot(relVelocity);
		if (b <= 0.0f)
		{
			if (-tmax*a <= b)
			{
				return a*c - b*b <= a*rSumSqr;
			}
			else
			{
				return tmax*(tmax*a + 2.0f*b) + c <= rSumSqr;
			}
		}
	}

	return c <= rSumSqr;
}
Esempio n. 7
0
//----------------------------------------------------------------------------
bool Camera::GetPickRay(float posSizePercentWdith, float posSizePercentHeight,
	APoint& origin, AVector& direction)
{
	// Get the [0,1]^2-normalized coordinates of (x,y).
	float r = posSizePercentWdith;
	float u = posSizePercentHeight;

	// Get the relative coordinates in [rmin,rmax]x[umin,umax].
	float rBlend = (1.0f - r)*GetRMin() + r*GetRMax();
	float uBlend = (1.0f - u)*GetUMin() + u*GetUMax();

	if (IsPerspective())
	{
		origin = GetPosition();
		direction = GetDMin()*GetDVector() +
			rBlend*GetRVector() + uBlend*GetUVector();
		direction.Normalize();
	}
	else
	{
		origin = GetPosition() + rBlend*GetRVector() +
			uBlend*GetUVector();
		direction = GetDVector();
		direction.Normalize();
	}

	return true;
}
//----------------------------------------------------------------------------
void TerrainPage::RemoveJunglerPoints (Jungler *jungler, APoint center, float radius, 
	int num)
{
	if (!jungler)
		return;

	// 范围内个数
	std::vector<int> indexs;
	for (int i=0; i<jungler->GetNum(); i++)
	{
		const APoint &pos = jungler->GetPos(i);
		AVector dir = pos - center;
		if (dir.Length() < radius)
		{
			indexs.push_back(i);
		}
	}

	std::vector<int> indexsRemoves;
	for (int i=0; i<(int)indexs.size(); i++)
	{
		float fRand = (float)num/(float)indexsRemoves.size();
		float fR = Mathf::IntervalRandom(0.0f, 1.0f);

		if (fR <= fRand)
		{
			indexsRemoves.push_back(indexs[i]);
		}
	}

	jungler->Remove(indexsRemoves);
}
//----------------------------------------------------------------------------
void EditRenderView_Scene::_RolateCamera(float horz, float vert)
{
	Scene *scene = PX2_PROJ.GetScene();
	CameraActor *camActor = scene->GetUseCameraActor();

	if (VT_PERSPECTIVE == mViewType)
	{
		AVector rVector;
		AVector dVector;
		AVector uVector;
		camActor->GetRDUVector(rVector, dVector, uVector);

		// horz
		HMatrix incrH(AVector::UNIT_Z, -horz*0.5f);
		dVector = incrH * dVector;
		uVector = incrH * uVector;
		rVector = incrH * rVector;

		// vert
		Matrix3f kIncrV(rVector, -vert*0.5f);
		dVector = kIncrV * dVector;
		uVector = kIncrV * uVector;

		dVector.Normalize();
		float dVectorAdj = dVector.Dot(AVector::UNIT_Z);
		float dVectorAdj1 = dVector.Dot(-AVector::UNIT_Z);
		if (dVectorAdj > 0.9f || dVectorAdj1 > 0.9f)
			return;

		AVector::Orthonormalize(dVector, uVector, rVector);
		camActor->LocalTransform.SetRotate(HMatrix(rVector, dVector,
			uVector, AVector::ZERO, true));
	}
}
Esempio n. 10
0
//----------------------------------------------------------------------------
bool ShadowMaps::OnInitialize ()
{
    if (!WindowApplication3::OnInitialize())
    {
        return false;
    }

    // Set up the camera.
    mCamera->SetFrustum(60.0f, 1.0f, 0.1f, 100.0f);
    APoint camPosition(8.0f, 0.0f, 4.0f);
    AVector camDVector = APoint::ORIGIN - camPosition;  // look at origin
    camDVector.Normalize();
    AVector camUVector(camDVector[2], 0, -camDVector[0]);
    AVector camRVector(0.0f, 1.0f, 0.0f);
    mCamera->SetFrame(camPosition, camDVector, camUVector, camRVector);

    CreateScene();

    // Initial update of objects.
    mScene->Update();

    // Initial culling of scene.
    mCuller.SetCamera(mCamera);
    mCuller.ComputeVisibleSet(mScene);

    InitializeCameraMotion(0.01f, 0.001f);
    InitializeObjectMotion(mScene);
    return true;
}
Esempio n. 11
0
//----------------------------------------------------------------------------
void PhysicsModule::GetData (APoint& center, HMatrix& incrRot) const
{
    // Position is a point exactly on the hill.
    APoint position;
    position[0] = (float)(A1*mState[0]);
    position[1] = (float)(A2*mState[2]);
    position[2] = (float)(A3 - mState[0]*mState[0] - mState[2]*mState[2]);

    // Lift this point off the hill in the normal direction by the radius of
    // the ball so that the ball just touches the hill.  The hill is
    // implicitly specified by F(x,y,z) = z - [a3 - (x/a1)^2 - (y/a2)^2]
    // where (x,y,z) is the position on the hill.  The gradient of F is a
    // normal vector, Grad(F) = (2*x/a1^2,2*y/a2^2,1).
    AVector normal;
    normal[0] = 2.0f*position[0]/(float)mAux[0];
    normal[1] = 2.0f*position[1]/(float)mAux[1];
    normal[2] = 1.0f;
    normal.Normalize();

    center = position + ((float)Radius)*normal;

    // Let the ball rotate as it rolls down hill.  The axis of rotation is
    // the perpendicular to hill normal and ball velocity.  The angle of
    // rotation from the last position is A = speed*deltaTime/radius.
    AVector velocity;
    velocity[0] = (float)(A1*mState[1]);
    velocity[1] = (float)(A1*mState[3]);
    velocity[2] = -2.0f*(velocity[0]*(float)mState[0] +
        velocity[1]*(float)mState[2]);

    float speed = velocity.Normalize();
    float angle = speed*((float)mDeltaTime)/((float)Radius);
    AVector axis = normal.UnitCross(velocity);
    incrRot = HMatrix(axis, angle);
}
Esempio n. 12
0
//----------------------------------------------------------------------------
void Fluids3D::UpdateIndexBuffer ()
{
    VertexBufferAccessor vba(mCube);
    APoint camPos = mCamera->GetPosition();
    const int numTriangles = mNumIndices/3;
    int* currentIndex = mIndices;

    mTriangles.clear();
    for (int t = 0; t < numTriangles; ++t)
    {
        Triangle tri;
        tri.mIndex0 = *currentIndex++;
        tri.mIndex1 = *currentIndex++;
        tri.mIndex2 = *currentIndex++;

#ifdef USE_PARTICLES
        float alpha = vba.Color<Float4>(0, tri.mIndex0)[3];
        if (alpha == 0.0f)
        {
            continue;
        }
#else
        float alpha0 = vba.Color<Float4>(0, tri.mIndex0)[3];
        float alpha1 = vba.Color<Float4>(0, tri.mIndex1)[3];
        float alpha2 = vba.Color<Float4>(0, tri.mIndex2)[3];
        if (alpha0 == 0.0f && alpha1 == 0.0f && alpha2 == 0.0f)
        {
            continue;
        }
#endif

        Vector3f scaledCenter =
            vba.Position<Vector3f>(tri.mIndex0) +
            vba.Position<Vector3f>(tri.mIndex1) +
            vba.Position<Vector3f>(tri.mIndex2);

        APoint output = mCube->WorldTransform*APoint(scaledCenter);
        AVector diff = output - camPos;
        tri.mNegSqrDistance = -diff.SquaredLength();

        mTriangles.insert(tri);
    }

    IndexBuffer* ibuffer = mCube->GetIndexBuffer();
    int* indices = (int*)ibuffer->GetData();
    ibuffer->SetNumElements(3*(int)mTriangles.size());

    std::multiset<Triangle>::iterator iter = mTriangles.begin();
    std::multiset<Triangle>::iterator end = mTriangles.end();
    for (/**/; iter != end; ++iter)
    {
        *indices++ = iter->mIndex0;
        *indices++ = iter->mIndex1;
        *indices++ = iter->mIndex2;
    }

    mRenderer->Update(ibuffer);
}
Esempio n. 13
0
AVector SteeringBehavior::Seek (APoint toPosition)
{
	AVector desiredVelocity = mActor->GetPosition() - actorPosition;
	desiredVelocity.Normalize();

	desiredVelocity *= mActor->GetMaxSpeed();

	return (desiredVelocity - mActor->GetVelocity());
}
Esempio n. 14
0
//----------------------------------------------------------------------------
AVector SurfacePatch::Tangent1 (float u, float v) const
{
    AVector tangent0 = PU(u, v);
    AVector tangent1 = PV(u, v);
    tangent0.Normalize();
    AVector normal = tangent0.UnitCross(tangent1);
    tangent1 = normal.Cross(tangent0);
    return tangent1;
}
Esempio n. 15
0
//----------------------------------------------------------------------------
void FMODSound::SetVelocity (const AVector &velocity)
{
    FMOD_VECTOR vec;
    vec.x = velocity.X();
    vec.y = velocity.Y();
    vec.z = velocity.Z();

    if (mChannel)
        mChannel->set3DAttributes(0, &vec);
}
Esempio n. 16
0
//----------------------------------------------------------------------------
AVector CurveSegment::Normal (float u) const
{
    AVector velocity = PU(u);
    AVector acceleration = PUU(u);
    float VDotV = velocity.Dot(velocity);
    float VDotA = velocity.Dot(acceleration);
    AVector normal = VDotV*acceleration - VDotA*velocity;
    normal.Normalize();
    return normal;
}
Esempio n. 17
0
//----------------------------------------------------------------------------
bool HelixTubeSurface::MoveCamera ()
{
    APoint position = mCurve->GetPosition(mCurveTime);
    AVector tangent = mCurve->GetTangent(mCurveTime);
    AVector binormal = tangent.UnitCross(AVector::UNIT_Z);
    AVector normal = binormal.UnitCross(tangent);
    mCamera->SetFrame(position, tangent, normal, binormal);
    mCuller.ComputeVisibleSet(mScene);
    return true;
}
Esempio n. 18
0
//----------------------------------------------------------------------------
void Soundable::UpdateWorldData(double applicationTime, double elapsedTime)
{
	Movable::UpdateWorldData(applicationTime, elapsedTime);

	if (mSound)
		mSound->SetPosition(WorldTransform.GetTranslate());

	const APoint &listenPos = SoundSystem::GetSingleton().GetListenerPos();

	if (!Is3D())
	{
		AVector dir = WorldTransform.GetTranslate() - listenPos;

		if (!mDistanceUseX)
			dir.X() = 0.0f;

		if (!mDistanceUseY)
			dir.Y() = 0.0f;

		if (!mDistanceUseZ)
			dir.Z() = 0.0f;

		float dist = dir.Length();

		SoundableController *sCtrl = DynamicCast<SoundableController>(GetEffectableController());
		const SoundableObject *sObj = sCtrl->GetSoundableObject();
		if (sObj)
		{
			float curVolume = sObj->Volume;
			float volume = curVolume;

			if (dist < mMinDistance)
			{
				volume = curVolume;
			}
			else if (mMinDistance<=dist && dist<=mMaxDistance)
			{
				float range = mMaxDistance - mMinDistance;
				if (range <= 0.0f)
					range = 0.0f;

				volume = curVolume * (1.0f - (dist - mMinDistance)/range);
			}
			else if (dist > mMaxDistance)
			{
				volume = 0.0f;
			}

			if (mSound)
			{
				mSound->SetVolume(volume);
			}
		}
	}
}
//----------------------------------------------------------------------------
bool PlanarShadowEffect::GetProjectionMatrix (int i, HMatrix& projection)
{
	// Compute the equation for the shadow plane in world coordinates.
	APoint vertex[3];
	mPlanes[i]->GetWorldTriangle(0, vertex);
	HPlane worldPlane(vertex[0], vertex[1], vertex[2]);

	// This is a conservative test to see whether a shadow should be cast.
	// This can cause incorrect results if the caster is large and intersects
	// the plane, but ordinarily we are not trying to cast shadows in such
	// situations.
	if (mShadowCaster->WorldBound.WhichSide(worldPlane) < 0)
	{
		// The shadow caster is on the far side of plane, so it cannot cast
		// a shadow.
		return false;
	}

	// Compute the projection matrix for the light source.
	Light* projector = mProjectors[i];
	AVector normal = worldPlane.GetNormal();
	if (projector->GetType() == Light::LT_DIRECTIONAL)
	{
		float NdD = normal.Dot(projector->DVector);
		if (NdD >= 0.0f)
		{
			// The projection must be onto the "positive side" of the plane.
			return false;
		}

		projection.MakeObliqueProjection(vertex[0], normal,
		                                 projector->DVector);
	}
	else if (projector->GetType() == Light::LT_POINT
	         ||  projector->GetType() == Light::LT_SPOT)
	{
		float NdE = projector->Position.Dot(normal);
		if (NdE <= 0.0f)
		{
			// The projection must be onto the "positive side" of the plane.
			return false;
		}

		projection.MakePerspectiveProjection(vertex[0], normal,
		                                     projector->Position);
	}
	else
	{
		assertion(false, "Light type not supported.\n");
		return false;
	}

	return true;
}
Esempio n. 20
0
//----------------------------------------------------------------------------
AVector Actor::GetFace()
{
	HMatrix matRot = LocalTransform.GetRotate();
	HPoint dir;
	matRot.GetColumn(1, dir);

	AVector vecDir = AVector(dir[0], dir[1], dir[2]);
	vecDir.Normalize();

	return vecDir;
}
Esempio n. 21
0
//----------------------------------------------------------------------------
AVector AVector::UnitCross (const AVector& vec) const
{
	AVector cross
		(
		mTuple[1]*vec.mTuple[2] - mTuple[2]*vec.mTuple[1],
		mTuple[2]*vec.mTuple[0] - mTuple[0]*vec.mTuple[2],
		mTuple[0]*vec.mTuple[1] - mTuple[1]*vec.mTuple[0]
	);

	cross.Normalize();
	return cross;
}
//----------------------------------------------------------------------------
void GamePlayApp::ZoomCamera (Camera *cam, float zoom)
{
	if (!cam)
		return;

	Vector3f position = cam->GetPosition();
	AVector dir = cam->GetDVector();
	dir.Normalize();

	position += dir*zoom;
	cam->SetPosition(position);
}
Esempio n. 23
0
//----------------------------------------------------------------------------
bool Bound::TestIntersection (const Bound& bound) const
{
	if (bound.GetRadius() == 0.0f || GetRadius() == 0.0f)
	{
		return false;
	}

	// 静态相交检测
	AVector diff = mCenter - bound.mCenter;
	float rSum = mRadius + bound.mRadius;
	return diff.SquaredLength() <= rSum*rSum;
}
//----------------------------------------------------------------------------
void PushTransformController::SetVelocity (const AVector &vec)
{
	AVector vecTemp = vec;
	float vecLength = vecTemp.Normalize();

	if (vecLength > mMaxVelocity)
	{
		vecLength = mMaxVelocity;
	}

	mVelocity = vecTemp*vecLength;
}
Esempio n. 25
0
//----------------------------------------------------------------------------
void EU_CanvasStage::_RoundCamera(float horz, float vert)
{
	if (!Project::GetSingletonPtr()) return;

	Scene *scene = PX2_PROJ.GetScene();
	if (!scene) return;

	if (mViewType == VT_PERSPECTIVE)
	{
		PX2::Object *obj = PX2_SELECTM_E->GetFirstObject();

		bool hasTarget = false;
		APoint pos;
		Movable *mov = DynamicCast<Movable>(obj);
		if (mov)
		{
			pos = mov->WorldTransform.GetTranslate();
			hasTarget = true;
		}

		if (hasTarget)
		{
			const APoint &camPos = mStageCameraNode->LocalTransform.GetTranslate();
			AVector rVector;
			AVector dVector;
			AVector uVector;
			mStageCameraNode->LocalTransform.GetRDUVector(rVector, dVector, uVector);

			AVector targetDir = pos - camPos;
			float targetLength = targetDir.Normalize();

			// horz
			HMatrix incrH(AVector::UNIT_Z, -horz*0.1f);
			targetDir = incrH * targetDir;
			dVector = incrH * dVector;
			uVector = incrH * uVector;
			rVector = incrH * rVector;

			HMatrix incrV(rVector, -vert*0.1f);
			targetDir = incrV * targetDir;
			dVector = incrV * dVector;
			uVector = incrV * uVector;

			APoint newPos = pos - targetDir*targetLength;
			mStageCameraNode->LocalTransform.SetTranslate(newPos);

			AVector::Orthonormalize(dVector, uVector, rVector);
			mStageCameraNode->LocalTransform.SetRotate(
				HMatrix(rVector, dVector, uVector, AVector::ZERO, true));
		}
	}
}
//----------------------------------------------------------------------------
void EditRenderView_Scene::_RoundCamera(float horz, float vert)
{
	Scene *scene = PX2_PROJ.GetScene();
	CameraActor *camActor = scene->GetUseCameraActor();

	if (mViewType == VT_PERSPECTIVE)
	{
		PX2::Object *obj = PX2_SELECTION.GetFirstObject();

		bool hasTarget = false;
		APoint pos;
		Movable *mov = DynamicCast<Movable>(obj);
		if (mov)
		{
			pos = mov->WorldTransform.GetTranslate();
			hasTarget = true;
		}

		if (hasTarget)
		{
			const APoint &camPos = camActor->LocalTransform.GetTranslate();
			AVector rVector;
			AVector dVector;
			AVector uVector;
			camActor->GetRDUVector(rVector, dVector, uVector);

			AVector targetDir = pos - camPos;
			float targetLength = targetDir.Normalize();

			// horz
			HMatrix incrH(AVector::UNIT_Z, -horz*0.1f);
			targetDir = incrH * targetDir;
			dVector = incrH * dVector;
			uVector = incrH * uVector;
			rVector = incrH * rVector;

			HMatrix incrV(rVector, -vert*0.1f);
			targetDir = incrV * targetDir;
			dVector = incrV * dVector;
			uVector = incrV * uVector;

			APoint newPos = pos - targetDir*targetLength;
			camActor->LocalTransform.SetTranslate(newPos);

			AVector::Orthonormalize(dVector, uVector, rVector);
			camActor->LocalTransform.SetRotate(
				HMatrix(rVector, dVector, uVector, AVector::ZERO, true));
		}
	}
}
Esempio n. 27
0
//----------------------------------------------------------------------------
void CameraActor::LookAt(const APoint &pos)
{
	APoint localPos = LocalTransform.GetTranslate();
	AVector dir = pos - localPos;

	float length = dir.Normalize();
	if (length > 0.0f)
	{
		AVector right = dir.UnitCross(AVector::UNIT_Z);
		AVector up = right.UnitCross(dir);

		LocalTransform.SetRotate(HMatrix(right, dir, up, AVector::ZERO, true));
	}
}
Esempio n. 28
0
//----------------------------------------------------------------------------
void SurfacePatch::GetFrame (float u, float v, APoint& position,
    AVector& tangent0, AVector& tangent1, AVector& normal) const
{
    position = P(u, v);

    tangent0 = PU(u, v);
    tangent1 = PV(u, v);
    tangent0.Normalize();
    normal = tangent0.UnitCross(tangent1);

    // The normalized first derivatives are not necessarily orthogonal.
    // Recompute T1 so that {T0,T1,N} is an orthonormal set.
    tangent1 = normal.Cross(tangent0);
}
Esempio n. 29
0
//----------------------------------------------------------------------------
void Renderable::GetVisibleSet (Culler& culler, bool)
{
	AdjustTransparent();

	const Camera *camera = culler.GetCamera();

	assertion(camera!=0, "camera must not be 0.");

	AVector cameraDir = camera->GetDVector();
	AVector diff = WorldBound.GetCenter() - camera->GetPosition();

	mEyeDistance = cameraDir.Dot(diff);

	culler.Insert(this);
}
Esempio n. 30
0
//----------------------------------------------------------------------------
void HMatrix::MakePerspectiveProjection (const APoint& origin,
    const AVector& normal, const APoint& eye)
{
    //     +-                                                 -+
    // M = | Dot(N,E-P)*I - E*N^T    -(Dot(N,E-P)*I - E*N^T)*E |
    //     |        -N^t                      Dot(N,E)         |
    //     +-                                                 -+
    //
    // where E is the eye point, P is a point on the plane, and N is a
    // unit-length plane normal.

    float dotND = normal.Dot(eye - origin);

    mEntry[ 0] = dotND - eye[0]*normal[0];
    mEntry[ 1] = -eye[0]*normal[1];
    mEntry[ 2] = -eye[0]*normal[2];
    mEntry[ 3] = -(mEntry[0]*eye[0] + mEntry[1]*eye[1] + mEntry[2]*eye[2]);
    mEntry[ 4] = -eye[1]*normal[0];
    mEntry[ 5] = dotND - eye[1]*normal[1];
    mEntry[ 6] = -eye[1]*normal[2];
    mEntry[ 7] = -(mEntry[4]*eye[0] + mEntry[5]*eye[1] + mEntry[6]*eye[2]);
    mEntry[ 8] = -eye[2]*normal[0];
    mEntry[ 9] = -eye[2]*normal[1];
    mEntry[10] = dotND- eye[2]*normal[2];
    mEntry[11] = -(mEntry[8]*eye[0] + mEntry[9]*eye[1] + mEntry[10]*eye[2]);
    mEntry[12] = -normal[0];
    mEntry[13] = -normal[1];
    mEntry[14] = -normal[2];
    mEntry[15] = eye.Dot(normal);
}