Пример #1
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;
}
//----------------------------------------------------------------------------
void AmbientRegionActor::_UpdateDirLightCamera()
{
	AVector dir = AVector::AnglesToDirection(Mathf::DEG_TO_RAD*mHorAngle,
		Mathf::DEG_TO_RAD*mVerAngle);
	dir.Normalize();

	Scene *scene = DynamicCast<Scene>(GetTopestParent());
	if (scene)
	{
		EnvirParam *envirParam = scene->GetEnvirParam();

		Light *lightDir = envirParam->GetLight_Dir();
		Projector *projector = envirParam->GetLight_Dir_Projector();

		lightDir->Ambient = Float4(mAmbientColor[0], mAmbientColor[1],
			mAmbientColor[2], mIntensity);
		lightDir->Intensity = mIntensity;
		lightDir->Diffuse = Float4(mDiffuseColor[0], mDiffuseColor[1],
			mDiffuseColor[2], 1.0f);
		lightDir->Specular = Float4(mSpecularColor[0], mSpecularColor[1],
			mSpecularColor[2], mSpecularPow);

		float upDot = dir.Dot(-AVector::UNIT_Z);
		if (upDot >= 0.99f)
		{
		}
		else
		{
			AVector upTemp = AVector::UNIT_Z;
			AVector right = dir.UnitCross(upTemp);
			AVector up = right.UnitCross(dir);

			lightDir->DVector = dir;
			lightDir->UVector = up;
			lightDir->RVector = right;

			APoint camPos = mLightCameraLookPosition - dir*mLightCameraLookDistance;
			projector->SetFrame(camPos, lightDir->DVector,
				lightDir->UVector, lightDir->RVector);
		}

		if (!projector->IsPerspective())
		{
			projector->SetFrustum(0.1f, 100.0f,
				-mLightCameraExtent, mLightCameraExtent, -mLightCameraExtent,
				mLightCameraExtent);
		}
		else
		{
			projector->SetFrustum(mLightCameraExtent, 1.0f, 1.0f, 100.0f);
		}
	}
}
Пример #3
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));
	}
}
Пример #4
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);
}
Пример #5
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);
}
Пример #6
0
//----------------------------------------------------------------------------
void SurfacePatch::ComputePrincipalCurvatureInfo (float u, float v,
    float& curv0, float& curv1, AVector& dir0, AVector& dir1)
{
    // Tangents:  T0 = dP/du = (x_u,y_u,z_u), T1 = dP/dv = (x_v,y_v,z_v)
    // Normal:    N = Cross(T0,T1)/Length(Cross(T0,T1))
    // Metric Tensor:    G = +-                      -+
    //                       | Dot(T0,T0)  Dot(T0,T1) |
    //                       | Dot(T1,T0)  Dot(T1,T1) |
    //                       +-                      -+
    //
    // Curvature Tensor:  B = +-                          -+
    //                        | -Dot(N,T0_u)  -Dot(N,T0_v) |
    //                        | -Dot(N,T1_u)  -Dot(N,T1_v) |
    //                        +-                          -+
    //
    // Principal curvatures k are the generalized eigenvalues of
    //
    //     Bw = kGw
    //
    // If k is a curvature and w=(a,b) is the corresponding solution to
    // Bw = kGw, then the principal direction as a 3D vector is d = a*U+b*V.
    //
    // Let k1 and k2 be the principal curvatures.  The mean curvature
    // is (k1+k2)/2 and the Gaussian curvature is k1*k2.

    // Compute the derivatives.
    AVector derU = PU(u, v);
    AVector derV = PV(u, v);
    AVector derUU = PUU(u, v);
    AVector derUV = PUV(u, v);
    AVector derVV = PVV(u, v);

    // Compute the metric tensor.
    float metricTensor[2][2];
    metricTensor[0][0] = derU.Dot(derU);
    metricTensor[0][1] = derU.Dot(derV);
    metricTensor[1][0] = metricTensor[0][1];
    metricTensor[1][1] = derV.Dot(derV);

    // Compute the curvature tensor.
    AVector normal = derU.UnitCross(derV);
    float curvatureTensor[2][2];
    curvatureTensor[0][0] = -normal.Dot(derUU);
    curvatureTensor[0][1] = -normal.Dot(derUV);
    curvatureTensor[1][0] = curvatureTensor[0][1];
    curvatureTensor[1][1] = -normal.Dot(derVV);

    // Characteristic polynomial is 0 = det(B-kG) = c2*k^2+c1*k+c0.
    float c0 = curvatureTensor[0][0]*curvatureTensor[1][1] -
        curvatureTensor[0][1]*curvatureTensor[1][0];
    float c1 = 2.0f*curvatureTensor[0][1]* metricTensor[0][1] -
        curvatureTensor[0][0]*metricTensor[1][1] -
        curvatureTensor[1][1]*metricTensor[0][0];
    float c2 = metricTensor[0][0]*metricTensor[1][1] -
        metricTensor[0][1]*metricTensor[1][0];

    // Principal curvatures are roots of characteristic polynomial.
    float temp = Mathf::Sqrt(Mathf::FAbs(c1*c1 - 4.0f*c0*c2));
    curv0 = -0.5f*(c1+temp);
    curv1 = 0.5f*(-c1+temp);

    // Principal directions are solutions to (B-kG)w = 0,
    // w1 = (b12-k1*g12,-(b11-k1*g11)) OR (b22-k1*g22,-(b12-k1*g12))
    float a0 = curvatureTensor[0][1] - curv0*metricTensor[0][1];
    float a1 = curv0*metricTensor[0][0] - curvatureTensor[0][0];
    float length = Mathf::Sqrt(a0*a0 + a1*a1);
    if (length >= Mathf::ZERO_TOLERANCE)
    {
        dir0 = a0*derU + a1*derV;
    }
    else
    {
        a0 = curvatureTensor[1][1] - curv0*metricTensor[1][1];
        a1 = curv0*metricTensor[0][1] - curvatureTensor[0][1];
        length = Mathf::Sqrt(a0*a0 + a1*a1);
        if (length >= Mathf::ZERO_TOLERANCE)
        {
            dir0 = a0*derU + a1*derV;
        }
        else
        {
            // Umbilic (surface is locally sphere, any direction principal).
            dir0 = derU;
        }
    }
    dir0.Normalize();

    // Second tangent is cross product of first tangent and normal.
    dir1 = dir0.Cross(normal);
}
Пример #7
0
//----------------------------------------------------------------------------
void Triangles::UpdateModelTangentsUseTCoords (VertexBufferAccessor& vba)
{
    // Each vertex can be visited multiple times, so compute the tangent
    // space only on the first visit.  Use the zero vector as a flag for the
    // tangent vector not being computed.
    const int numVertices = vba.GetNumVertices();
    bool hasTangent = vba.HasTangent();
    Float3 zero(0.0f, 0.0f, 0.0f);
    int i;
    if (hasTangent)
    {
        for (i = 0; i < numVertices; ++i)
        {
            vba.Tangent<Float3>(i) = zero;
        }
    }
    else
    {
        for (i = 0; i < numVertices; ++i)
        {
            vba.Binormal<Float3>(i) = zero;
        }
    }

    const int numTriangles = GetNumTriangles();
    for (i = 0; i < numTriangles; i++)
    {
        // Get the triangle vertices' positions, normals, tangents, and
        // texture coordinates.
        int v0, v1, v2;
        if (!GetTriangle(i, v0, v1, v2))
        {
            continue;
        }

        APoint locPosition[3] =
        {
            vba.Position<Float3>(v0),
            vba.Position<Float3>(v1),
            vba.Position<Float3>(v2)
        };

        AVector locNormal[3] =
        {
            vba.Normal<Float3>(v0),
            vba.Normal<Float3>(v1),
            vba.Normal<Float3>(v2)
        };

        AVector locTangent[3] =
        {
            (hasTangent ? vba.Tangent<Float3>(v0) : vba.Binormal<Float3>(v0)),
            (hasTangent ? vba.Tangent<Float3>(v1) : vba.Binormal<Float3>(v1)),
            (hasTangent ? vba.Tangent<Float3>(v2) : vba.Binormal<Float3>(v2))
        };

        Float2 locTCoord[3] =
        {
            vba.TCoord<Float2>(0, v0),
            vba.TCoord<Float2>(0, v1),
            vba.TCoord<Float2>(0, v2)
        };

        for (int curr = 0; curr < 3; ++curr)
        {
            Float3 currLocTangent = (Float3)locTangent[curr];
            if (currLocTangent != zero)
            {
                // This vertex has already been visited.
                continue;
            }

            // Compute the tangent space at the vertex.
            AVector norvec = locNormal[curr];
            int prev = ((curr + 2) % 3);
            int next = ((curr + 1) % 3);
            AVector tanvec = ComputeTangent(
                locPosition[curr], locTCoord[curr],
                locPosition[next], locTCoord[next],
                locPosition[prev], locTCoord[prev]);

            // Project T into the tangent plane by projecting out the surface
            // normal N, and then making it unit length.
            tanvec -= norvec.Dot(tanvec)*norvec;
            tanvec.Normalize();

            // Compute the bitangent B, another tangent perpendicular to T.
            AVector binvec = norvec.UnitCross(tanvec);

            if (vba.HasTangent())
            {
                locTangent[curr] = tanvec;
                if (vba.HasBinormal())
                {
                    vba.Binormal<Float3>(curr) = binvec;
                }
            }
            else
            {
                vba.Binormal<Float3>(curr) = tanvec;
            }
        }
    }
}