//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); } }
//---------------------------------------------------------------------------- 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; } }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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)); } }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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); }
AVector SteeringBehavior::Seek (APoint toPosition) { AVector desiredVelocity = mActor->GetPosition() - actorPosition; desiredVelocity.Normalize(); desiredVelocity *= mActor->GetMaxSpeed(); return (desiredVelocity - mActor->GetVelocity()); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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)); } } }
//---------------------------------------------------------------------------- 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)); } }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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); }