Beispiel #1
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;
}
//----------------------------------------------------------------------------
bool InputPushTransformController::IsSmallTransScope()
{
	AVector smallScope = mMaxPosSmall - mMinPosSmall;
	float lengthSquare = smallScope.SquaredLength();

	return 0.0f != lengthSquare;
}
Beispiel #3
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);
}
Beispiel #4
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 Scene::GetRangeActors (std::vector<Actor*> &actors, const APoint &center, 
	float radius, bool useActorSelfRadius, const std::bitset<16> &bits)
{
	actors.clear();

	if (SMT_NONE == mSceneManageType)
	{
		for (int i=0; i<GetNumActors(); i++)
		{
			Actor *actor = GetActor(i);
			if (!actor->IsVisible())
				continue;

			const APoint &pos = actor->GetPosition();
			AVector dir = pos - center;
			float lengthSquare = dir.SquaredLength();

			float adjustLength = radius;
			if (useActorSelfRadius)
			{
				adjustLength += actor->GetSelfRadius();
			}

			if (lengthSquare < adjustLength*adjustLength)
			{
				if (actor->IsContainAllBits(bits))
				{
					actors.push_back(actor);
				}
			}
		}
	}
	else
	{
		if (SMT_OCTREE == mSceneManageType)
		{
		}
		else if (SMT_CELL2D == mSceneManageType)
		{
			mCellSpace->CalculateNeighbors(actors, center, radius, 
				useActorSelfRadius, bits);
		}
	}
}
Beispiel #6
0
//----------------------------------------------------------------------------
float CurveSegment::Curvature (float u) const
{
    AVector velocity = PU(u);
    float speedSqr = velocity.SquaredLength();

    if (speedSqr >= Mathf::ZERO_TOLERANCE)
    {
        AVector acceleration = PUU(u);
        AVector cross = velocity.Cross(acceleration);
        float numer = cross.Length();
        float denom = Mathf::Pow(speedSqr, 1.5f);
        return numer/denom;
    }
    else
    {
        // Curvature is indeterminate, just return 0.
        return 0.0f;
    }
}
Beispiel #7
0
//----------------------------------------------------------------------------
float CurveSegment::Torsion (float u) const
{
    AVector velocity = PU(u);
    AVector acceleration = PUU(u);
    AVector cross = velocity.Cross(acceleration);
    float denom = cross.SquaredLength();

    if (denom >= Mathf::ZERO_TOLERANCE)
    {
        AVector jerk = PUUU(u);
        float numer = cross.Dot(jerk);
        return numer/denom;
    }
    else
    {
        // Torsion is indeterminate, just return 0.
        return 0.0f;
    }
}
//----------------------------------------------------------------------------
void Scene::GetRangeActors(std::vector<Actor*> &actors, const APoint &center,
	float radius, bool useActorSelfRadius, const std::bitset<PX2_ACTOR_BS_SIZE> &bits)
{
	actors.clear();

	if (SMT_NONE == mSceneManageType)
	{
		for (int i = 0; i < GetNumChildren(); i++)
		{
			Actor *actor = DynamicCast<Actor>(GetChild(i));
			if (!actor->IsShow()) continue;

			const APoint &pos = actor->LocalTransform.GetTranslate();
			AVector dir = pos - center;
			float lengthSquare = dir.SquaredLength();

			float adjustLength = radius;
			if (useActorSelfRadius)
			{
				adjustLength += actor->GetRadius();
			}

			if (lengthSquare < adjustLength*adjustLength)
			{
				if (actor->IsContainAllBits(bits))
				{
					actors.push_back(actor);
				}
			}
		}
	}
	else
	{
		if (SMT_OCTREE == mSceneManageType)
		{
		}
		else if (SMT_CELL2D == mSceneManageType)
		{
			mCellSpace->CalculateNeighbors(actors, center, radius,
				useActorSelfRadius, bits);
		}
	}
}
Beispiel #9
0
//-----------------------------------------------------------------------------
void CellSpace::CalculateNeighbors(std::vector<Actor*> &actors,
	const APoint &targetPos, float queryRadius, bool useActorSelfRadius,
	const std::bitset<PX2_ACTOR_BS_SIZE> &bits)
{
	AVector radiusDir = AVector(queryRadius, queryRadius, queryRadius);
	APoint min = targetPos - radiusDir;
	APoint max = targetPos + radiusDir;

	AxisAlignedBox3f queryBox(min, max);

	std::vector<Cell>::iterator curCell = mCells.begin();
	for (; curCell != mCells.end(); ++curCell)
	{
		if (curCell->AlignedBox.TestIntersection(queryBox) &&
			!curCell->Members.empty())
		{
			std::list<Actor*>::iterator it = curCell->Members.begin();
			for (; it != curCell->Members.end(); ++it)
			{
				if (!(*it)->IsShow())
					continue;

				AVector disDir = (*it)->LocalTransform.GetTranslate() - targetPos;
				float distanceSquared = disDir.SquaredLength();

				float adjustDist = queryRadius;
				if (useActorSelfRadius)
				{
					adjustDist += (*it)->GetRadius();
				}

				if (distanceSquared <= adjustDist*adjustDist)
				{
					if ((*it)->IsContainAllBits(bits))
					{
						actors.push_back(*it);
					}
				}
			}
		}
	}
}
Beispiel #10
0
//----------------------------------------------------------------------------
void Bound::GrowToContain (const Bound& bound)
{
	if (bound.GetRadius() == 0.0f)
	{
		// The node is a dummy node and cannot affect growth.
		return;
	}

	if (GetRadius() == 0.0f)
	{
		mCenter = bound.GetCenter();
		mRadius = bound.GetRadius();
		
		return;
	}

	AVector centerDiff = bound.mCenter - mCenter;
	float lengthSqr = centerDiff.SquaredLength();
	float radiusDiff = bound.mRadius - mRadius;
	float radiusDiffSqr = radiusDiff*radiusDiff;

	if (radiusDiffSqr >= lengthSqr)
	{
		if (radiusDiff >= 0.0f)
		{
			mCenter = bound.mCenter;
			mRadius = bound.mRadius;
		}
		return;
	}

	float length = Mathf::Sqrt(lengthSqr);
	if (length > Mathf::ZERO_TOLERANCE)
	{
		float coeff = (length + radiusDiff)/(2.0f*length);
		mCenter += coeff*centerDiff;
	}

	mRadius = 0.5f*(length + mRadius + bound.mRadius);
}
Beispiel #11
0
//----------------------------------------------------------------------------
void VolumeTextures::CreateScene ()
{
	mScene = new0 Node();
	mAlphaState = new0 AlphaState();
	mAlphaState->BlendEnabled = true;
	mRenderer->SetOverrideAlphaState(mAlphaState);
	mCullState = new0 CullState();
	mCullState->Enabled = false;
	mRenderer->SetOverrideCullState(mCullState);

	// Create the grid of square meshes.
	const int numSlices = 64;
	const int numSamples = 32;

	// The vertex format that is shared by all square meshes.
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT3, 0);
	int vstride = vformat->GetStride();

	// The index buffer that is shared by all square meshes.
	int numIndices = 6*(numSamples-1)*(numSamples-1);
	IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
	int* indices = (int*)ibuffer->GetData();
	for (int i1 = 0; i1 < numSamples - 1; ++i1)
	{
		for (int i0 = 0; i0 < numSamples - 1; ++i0)
		{
			int v0 = i0 + numSamples * i1;
			int v1 = v0 + 1;
			int v2 = v1 + numSamples;
			int v3 = v0 + numSamples;
			*indices++ = v0;
			*indices++ = v1;
			*indices++ = v2;
			*indices++ = v0;
			*indices++ = v2;
			*indices++ = v3;
		}
	}

	// Create the volume texture.  Three Gaussian distributions are used for
	// the RGB color channels.  The alpha channel is constant.
	const int bound = 64;
	Texture3D* texture = new0 Texture3D(Texture::TF_A8R8G8B8, bound, bound,
	                                    bound, 1);
	unsigned char* data = (unsigned char*)texture->GetData(0);
	const float mult = 1.0f/(bound - 1.0f);
	const float rParam = 0.01f;
	const float gParam = 0.01f;
	const float bParam = 0.01f;
	const float extreme = 8.0f;
	APoint rCenter( 0.5f*extreme,  0.0f,         0.0f);
	APoint gCenter(-0.5f*extreme, -0.5f*extreme, 0.0f);
	APoint bCenter(-0.5f*extreme, +0.5f*extreme, 0.0f);
	unsigned char commonAlpha = 12;
	APoint point;
	for (int z = 0; z < bound; ++z)
	{
		point[2] = -extreme + 2.0f*extreme*mult*z;
		for (int y = 0; y < bound; ++y)
		{
			point[1] = -extreme + 2.0f*extreme*mult*y;
			for (int x = 0; x < bound; ++x)
			{
				point[0] = -extreme + 2.0f*extreme*mult*x;

				AVector diff = point - rCenter;
				float sqrLength = diff.SquaredLength();
				float rGauss = 1.0f - rParam*sqrLength;
				if (rGauss < 0.0f)
				{
					rGauss = 0.0f;
				}

				diff = point - gCenter;
				sqrLength = diff.SquaredLength();
				float gGauss = 1.0f - gParam*sqrLength;
				if (gGauss < 0.0f)
				{
					gGauss = 0.0f;
				}

				diff = point - bCenter;
				sqrLength = diff.SquaredLength();
				float bGauss = 1.0f - bParam*sqrLength;
				if (bGauss < 0.0f)
				{
					bGauss = 0.0f;
				}

				*data++ = (unsigned char)(255.0f*bGauss);
				*data++ = (unsigned char)(255.0f*gGauss);
				*data++ = (unsigned char)(255.0f*rGauss);
				*data++ = commonAlpha;
			}
		}
	}

	// The volume texture effect that is shared by all square meshes.
	std::string effectFile = Environment::GetPathR("VolumeTextures.wmfx");
	VolumeTextureEffect* effect = new0 VolumeTextureEffect(effectFile);
	VisualEffectInstance* instance = effect->CreateInstance(texture);

	// The grid of squares.
	const int numVertices = numSamples*numSamples;
	float inv = 1.0f/(numSamples - 1.0f);
	VertexBufferAccessor vba;
	for (int slice = 0; slice < numSlices; ++slice)
	{
		VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
		vba.ApplyTo(vformat, vbuffer);

		float w = slice/(numSlices - 1.0f);
		float z = 2.0f*w - 1.0f;
		for (int i1 = 0, i = 0; i1 < numSamples; ++i1)
		{
			float v = i1*inv;
			float y = 2.0f*v - 1.0f;
			for (int i0 = 0; i0 < numSamples; ++i0, ++i)
			{
				float u = i0*inv;
				float x = 2.0f*u - 1.0f;
				vba.Position<Float3>(i) = Float3(x, y, z);
				vba.TCoord<Float3>(0, i) = Float3(u, v, w);
			}
		}

		TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
		mesh->SetEffectInstance(instance);
		mScene->AttachChild(mesh);
	}
}