Esempio n. 1
0
//----------------------------------------------------------------------------
void BouncingBall::CreateFloor ()
{
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    const float xExtent = 8.0f;
    const float yExtent = 16.0f;
    const float zValue = 0.0f;
    vba.Position<Float3>(0) = Float3(-xExtent, -yExtent, zValue);
    vba.Position<Float3>(1) = Float3(+xExtent, -yExtent, zValue);
    vba.Position<Float3>(2) = Float3(+xExtent, +yExtent, zValue);
    vba.Position<Float3>(3) = Float3(-xExtent, +yExtent, zValue);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
    indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

    mFloor = new0 TriMesh(vformat, vbuffer, ibuffer);

    std::string path = Environment::GetPathR("Floor.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    mFloor->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture,
        Shader::SF_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT));
}
//----------------------------------------------------------------------------
TriMesh *ScreenTarget::CreateRectangle (VertexFormat* vformat, 
	float xMin,	float xMax, float yMin, float yMax, float zValue)
{
	if (!ValidFormat(vformat))
		return 0;

	Float2 tc0, tc1, tc2, tc3;
	tc0 = Float2(0.0f, 0.0f);
	tc1 = Float2(1.0f, 0.0f);
	tc2 = Float2(1.0f, 1.0f);
	tc3 = Float2(0.0f, 1.0f);

	int vstride = vformat->GetStride();
	VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
	VertexBufferAccessor vba(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(xMin, yMin, zValue);
	vba.Position<Float3>(1) = Float3(xMax, yMin, zValue);
	vba.Position<Float3>(2) = Float3(xMax, yMax, zValue);
	vba.Position<Float3>(3) = Float3(xMin, yMax, zValue);
	vba.TCoord<Float2>(0, 0) = tc0;
	vba.TCoord<Float2>(0, 1) = tc1;
	vba.TCoord<Float2>(0, 2) = tc2;
	vba.TCoord<Float2>(0, 3) = tc3;

	// 为square创建IndexBuffer
	IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
	int* indices = (int*)ibuffer->GetData();
	indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
	indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

	return new0 TriMesh(vformat, vbuffer, ibuffer);
}
Esempio n. 3
0
//----------------------------------------------------------------------------
Billboard::Billboard () :
mIsDynamic(true),
mIsUseTexAsSize(false),
mIsDoAlphaDisAfterStop(true),
mDoAlphaDisAfterStopSpeed(0.5f),
mIsUseTrim(false)
{
	SetTex("Data/engine/default.png");

	mAnchorPoint = Float2(0.5f, 0.5f);

	SetLocal(true);
	SetDynamic(mIsDynamic);

	IndexBuffer *iBuffer = new0 IndexBuffer(6, 2, Buffer::BU_STATIC);
	unsigned short *indices = (unsigned short*)iBuffer->GetData();
	unsigned short v0 = 0;
	unsigned short v1 = 1;
	unsigned short v2 = 2;
	unsigned short v3 = 3;
	*indices++ = v0;
	*indices++ = v1;
	*indices++ = v2;
	*indices++ = v1;
	*indices++ = v3;
	*indices++ = v2;
	SetIndexBuffer(iBuffer);

	mEffectableCtrl = new0 BillboardController();
	mEffectableCtrl->SetName("BillboardController");
	AttachController(mEffectableCtrl);
}
Esempio n. 4
0
//----------------------------------------------------------------------------
TriMesh* PolyhedronDistance::CreatePlane ()
{
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    float size = 16.0f;
    vba.Position<Float3>(0) = Float3(-size, -size, -0.1f);
    vba.Position<Float3>(1) = Float3(+size, -size, -0.1f);
    vba.Position<Float3>(2) = Float3(+size, +size, -0.1f);
    vba.Position<Float3>(3) = Float3(-size, +size, -0.1f);
    vba.Color<Float3>(0, 0) = Float3(0.0f, 0.50f, 0.00f);
    vba.Color<Float3>(0, 1) = Float3(0.0f, 0.25f, 0.00f);
    vba.Color<Float3>(0, 2) = Float3(0.0f, 0.75f, 0.00f);
    vba.Color<Float3>(0, 3) = Float3(0.0f, 1.00f, 0.00f);

    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0; indices[1] = 1; indices[2] = 2;
    indices[3] = 0; indices[4] = 2; indices[5] = 3;

    TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
    mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

    return mesh;
}
Esempio n. 5
0
//----------------------------------------------------------------------------
void BouncingSpheres::CreateBackWall ()
{
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    Float3 backWallColor(209.0f/255.0f, 204.0f/255.0f, 180.0f/255.0f);

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(1.0f,  1.0f,  1.0f);
    vba.Position<Float3>(1) = Float3(1.0f, 20.0f,  1.0f);
    vba.Position<Float3>(2) = Float3(1.0f, 20.0f, 17.0f);
    vba.Position<Float3>(3) = Float3(1.0f,  1.0f, 17.0f);
    vba.Color<Float3>(0, 0) = backWallColor;
    vba.Color<Float3>(0, 1) = backWallColor;
    vba.Color<Float3>(0, 2) = backWallColor;
    vba.Color<Float3>(0, 3) = backWallColor;

    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
    indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

    mBackWall = new0 TriMesh(vformat, vbuffer, ibuffer);
    mBackWall->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());
}
Esempio n. 6
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. 7
0
//----------------------------------------------------------------------------
void ClipMesh::Update ()
{
    // Transform the model-space vertices to world space.
    int numVertices = (int)mTorusVerticesMS.size();
    int i;
    for (i = 0; i < numVertices; ++i)
    {
        mTorusVerticesWS[i] = mTorus->LocalTransform*mTorusVerticesMS[i];
    }

    // Partition the torus mesh.
    std::vector<APoint> clipVertices;
    std::vector<int> negIndices, posIndices;
    PartitionMesh(mTorusVerticesWS, mTorusIndices, mPlane, clipVertices,
        negIndices, posIndices);

    // Replace the torus vertex buffer.
    numVertices = (int)clipVertices.size();
    int stride = mTorus->GetVertexFormat()->GetStride();
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride,
        Buffer::BU_STATIC);
    mTorus->SetVertexBuffer(vbuffer);
    VertexBufferAccessor vba(mTorus);
    Float3 black(0.0f, 0.0f, 0.0f);
    for (i = 0; i < numVertices; ++i)
    {
        // Transform the world-space vertex to model space.
        vba.Position<Float3>(i) =
            mTorus->LocalTransform.Inverse()*clipVertices[i];

        vba.Color<Float3>(0, i) = black;
    }

    // Modify the vertex color based on which mesh the vertices lie.
    int negQuantity = (int)negIndices.size();
    for (i = 0; i < negQuantity; ++i)
    {
        vba.Color<Float3>(0, negIndices[i])[2] = 1.0f;
    }
    int posQuantity = (int)posIndices.size();
    for (i = 0; i < posQuantity; ++i)
    {
        vba.Color<Float3>(0, posIndices[i])[0] = 1.0f;
    }

    // To display the triangles generated by the split.
    int numIndices = negQuantity + posQuantity;
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    mTorus->SetIndexBuffer(ibuffer);
    int* indices = (int*)ibuffer->GetData();
    memcpy(indices, &negIndices[0], negQuantity*sizeof(int));
    memcpy(indices + negQuantity, &posIndices[0], posQuantity*sizeof(int));
}
Esempio n. 8
0
//----------------------------------------------------------------------------
void ClipMesh::CreateScene ()
{
    mScene = new0 Node();

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);

    // The plane is fixed at z = 0.
    mPlane.SetNormal(AVector::UNIT_Z);
    mPlane.SetConstant(0.0f);
    mMeshPlane = StandardMesh(vformat).Rectangle(32, 32, 16.0f, 16.0f);
    VisualEffectInstance* instance =
        VertexColor3Effect::CreateUniqueInstance();
    instance->GetEffect()->GetWireState(0,0)->Enabled = true;
    mMeshPlane->SetEffectInstance(instance);
    mScene->AttachChild(mMeshPlane);

    VertexBufferAccessor vba(mMeshPlane);
    Float3 green(0.0f, 1.0f, 0.0f);
    int i;
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = green;
    }

    // Get the positions and indices for a torus.
    mTorus = StandardMesh(vformat).Torus(64, 64, 4.0f, 1.0f);
    instance = VertexColor3Effect::CreateUniqueInstance();
    mTorusWireState = instance->GetEffect()->GetWireState(0, 0);
    mTorus->SetEffectInstance(instance);
    mScene->AttachChild(mTorus);

    vba.ApplyTo(mTorus);
    mTorusVerticesMS.resize(vba.GetNumVertices());
    mTorusVerticesWS.resize(vba.GetNumVertices());
    Float3 black(0.0f, 0.0f, 0.0f);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        mTorusVerticesMS[i] = vba.Position<Float3>(i);
        mTorusVerticesWS[i] = mTorusVerticesMS[i];
        vba.Color<Float3>(0, i) = black;
    }

    IndexBuffer* ibuffer = mTorus->GetIndexBuffer();
    int numIndices = ibuffer->GetNumElements();
    int* indices = (int*)ibuffer->GetData();
    mTorusIndices.resize(numIndices);
    memcpy(&mTorusIndices[0], indices, numIndices*sizeof(int));

    Update();
}
//----------------------------------------------------------------------------
TriMesh* ScreenTarget::CreateRectangle (VertexFormat* vformat, int rtWidth,
										int rtHeight, float xmin, float xmax, float ymin, float ymax,
										float zValue)
{
	if (ValidFormat(vformat) && ValidSizes(rtWidth, rtHeight))
	{
		Float2 tc0, tc1, tc2, tc3;
		if (VertexShader::GetProfile() == VertexShader::VP_ARBVP1)
		{
			tc0 = Float2(0.0f, 0.0f);
			tc1 = Float2(1.0f, 0.0f);
			tc2 = Float2(1.0f, 1.0f);
			tc3 = Float2(0.0f, 1.0f);
		}
		else
		{
			float dx = 0.5f*(xmax - xmin)/(float)(rtWidth - 1);
			float dy = 0.5f*(ymax - ymin)/(float)(rtHeight - 1);
			xmin -= dx;
			xmax -= dx;
			ymin += dy;
			ymax += dy;
			tc0 = Float2(0.0f, 1.0f);
			tc1 = Float2(1.0f, 1.0f);
			tc2 = Float2(1.0f, 0.0f);
			tc3 = Float2(0.0f, 0.0f);
		}

		int vstride = vformat->GetStride();
		VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
		VertexBufferAccessor vba(vformat, vbuffer);
		vba.Position<Float3>(0) = Float3(xmin, ymin, zValue);
		vba.Position<Float3>(1) = Float3(xmax, ymin, zValue);
		vba.Position<Float3>(2) = Float3(xmax, ymax, zValue);
		vba.Position<Float3>(3) = Float3(xmin, ymax, zValue);
		vba.TCoord<Float2>(0, 0) = tc0;
		vba.TCoord<Float2>(0, 1) = tc1;
		vba.TCoord<Float2>(0, 2) = tc2;
		vba.TCoord<Float2>(0, 3) = tc3;

		// 为square创建IndexBuffer
		IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
		int* indices = (int*)ibuffer->GetData();
		indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
		indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

		return new0 TriMesh(vformat, vbuffer, ibuffer);
	}

	return 0;
}
Esempio n. 10
0
//----------------------------------------------------------------------------
TriMesh* StandardMesh::Hexahedron ()
{
    float fSqrtThird = Mathf::Sqrt(1.0f/3.0f);

    int numVertices = 8;
    int numTriangles = 12;
    int numIndices = 3*numTriangles;
    int stride = mVFormat->GetStride();

    // Create a vertex buffer.
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride, mUsage);

    VertexBufferAccessor vba(mVFormat, vbuffer);

    // Generate geometry.
    vba.Position<Float3>(0) = Float3(-fSqrtThird, -fSqrtThird, -fSqrtThird);
    vba.Position<Float3>(1) = Float3( fSqrtThird, -fSqrtThird, -fSqrtThird);
    vba.Position<Float3>(2) = Float3( fSqrtThird,  fSqrtThird, -fSqrtThird);
    vba.Position<Float3>(3) = Float3(-fSqrtThird,  fSqrtThird, -fSqrtThird);
    vba.Position<Float3>(4) = Float3(-fSqrtThird, -fSqrtThird,  fSqrtThird);
    vba.Position<Float3>(5) = Float3( fSqrtThird, -fSqrtThird,  fSqrtThird);
    vba.Position<Float3>(6) = Float3( fSqrtThird,  fSqrtThird,  fSqrtThird);
    vba.Position<Float3>(7) = Float3(-fSqrtThird,  fSqrtThird,  fSqrtThird);
    CreatePlatonicNormals(vba);
    CreatePlatonicUVs(vba);
    TransformData(vba);

    // Generate indices.
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage);
    int* indices = (int*)ibuffer->GetData();
    indices[ 0] = 0;  indices[ 1] = 3;  indices[ 2] = 2;
    indices[ 3] = 0;  indices[ 4] = 2;  indices[ 5] = 1;
    indices[ 6] = 0;  indices[ 7] = 1;  indices[ 8] = 5;
    indices[ 9] = 0;  indices[10] = 5;  indices[11] = 4;
    indices[12] = 0;  indices[13] = 4;  indices[14] = 7;
    indices[15] = 0;  indices[16] = 7;  indices[17] = 3;
    indices[18] = 6;  indices[19] = 5;  indices[20] = 1;
    indices[21] = 6;  indices[22] = 1;  indices[23] = 2;
    indices[24] = 6;  indices[25] = 2;  indices[26] = 3;
    indices[27] = 6;  indices[28] = 3;  indices[29] = 7;
    indices[30] = 6;  indices[31] = 7;  indices[32] = 4;
    indices[33] = 6;  indices[34] = 4;  indices[35] = 5;

    if (mInside)
    {
        ReverseTriangleOrder(numTriangles,indices);
    }

    return new0 TriMesh(mVFormat, vbuffer, ibuffer);
}
Esempio n. 11
0
//----------------------------------------------------------------------------
Node* ExtremalQuery::CreateVisualConvexPolyhedron ()
{
    const Vector3f* vertices = mConvexPolyhedron->GetVertices();
    int numTriangles = mConvexPolyhedron->GetNumTriangles();
    int numIndices = 3*numTriangles;
    const int* polyIndices = mConvexPolyhedron->GetIndices();

    // Visualize the convex polyhedron as a collection of face-colored
    // triangles.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(numIndices, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    int* indices = (int*)ibuffer->GetData();

    int i;
    for (i = 0; i < numIndices; ++i)
    {
        vba.Position<Vector3f>(i) = vertices[polyIndices[i]];
        indices[i] = i;
    }

    TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer);

    // Use randomly generated vertex colors.
    for (i = 0; i < numTriangles; ++i)
    {
        Float3 color;
        for (int j = 0; j < 3; ++j)
        {
            color[j] = Mathf::UnitRandom();
        }

        vba.Color<Float3>(0, 3*i  ) = color;
        vba.Color<Float3>(0, 3*i+1) = color;
        vba.Color<Float3>(0, 3*i+2) = color;
    }

    mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

    Node* root = new0 Node();
    root->AttachChild(mesh);
    return root;
}
Esempio n. 12
0
//----------------------------------------------------------------------------
void IntersectTriangleCylinder::CreateScene ()
{
    mScene = new0 Node();
    mCullState = new0 CullState();
    mCullState->Enabled = false;
    mRenderer->SetOverrideCullState(mCullState);
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    VertexFormat* vformat = VertexFormat::Create(2,
                            VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
                            VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(3, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    vba.Position<Vector3f>(0) = (const Vector3f&)mTriangleMVertex0;
    vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 1.0f);
    vba.Position<Vector3f>(1) = (const Vector3f&)mTriangleMVertex1;
    vba.Color<Float3>(0, 1) = Float3(0.0f, 0.0f, 1.0f);
    vba.Position<Vector3f>(2) = (const Vector3f&)mTriangleMVertex2;
    vba.Color<Float3>(0, 2) = Float3(0.0f, 0.0f, 1.0f);

    IndexBuffer* ibuffer = new0 IndexBuffer(3, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;
    indices[1] = 1;
    indices[2] = 2;
    mTMesh = new0 TriMesh(vformat, vbuffer, ibuffer);
    mTMesh->SetEffectInstance(
        VertexColor3Effect::CreateUniqueInstance());
    mTMesh->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f));

    mCMesh = StandardMesh(vformat).Cylinder(8, 16, mCylinderRadius,
                                            mCylinderHeight, false);
    vba.ApplyTo(mCMesh);
    for (int i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = Float3(1.0f, 0.0f, 0.0f);
    }
    mCMesh->SetEffectInstance(
        VertexColor3Effect::CreateUniqueInstance());

    mScene->AttachChild(mTMesh);
    mScene->AttachChild(mCMesh);
}
Esempio n. 13
0
//----------------------------------------------------------------------------
TriMesh* RoughPlaneSolidBox::CreateRamp ()
{
    float x = 8.0f;
    float y = 8.0f;
    float z = y*Mathf::Tan((float)mModule.Angle);

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(6, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    vba.Position<Float3>(0) = Float3(-x, 0.0f, 0.0f);
    vba.Position<Float3>(1) = Float3(+x, 0.0f, 0.0f);
    vba.Position<Float3>(2) = Float3(-x, y, 0.0f);
    vba.Position<Float3>(3) = Float3(+x, y, 0.0f);
    vba.Position<Float3>(4) = Float3(-x, y, z);
    vba.Position<Float3>(5) = Float3(+x, y, z);
    vba.TCoord<Float2>(0, 0) = Float2(0.25f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(0.75f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    vba.TCoord<Float2>(0, 4) = Float2(0.25f, 1.0f);
    vba.TCoord<Float2>(0, 5) = Float2(0.75f, 1.0f);

    IndexBuffer* ibuffer = new0 IndexBuffer(18, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[ 0] = 0;  indices[ 1] = 1;  indices[ 2] = 4;
    indices[ 3] = 1;  indices[ 4] = 5;  indices[ 5] = 4;
    indices[ 6] = 0;  indices[ 7] = 4;  indices[ 8] = 2;
    indices[ 9] = 1;  indices[10] = 3;  indices[11] = 5;
    indices[12] = 3;  indices[13] = 2;  indices[14] = 4;
    indices[15] = 3;  indices[16] = 4;  indices[17] = 5;

    TriMesh* ramp = new0 TriMesh(vformat, vbuffer, ibuffer);

    std::string path = Environment::GetPathR("Metal.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    ramp->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture,
        Shader::SF_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT));

    return ramp;
}
Esempio n. 14
0
//----------------------------------------------------------------------------
TriMesh* PolyhedronDistance::CreateTetra (float size, bool isBlack)
{
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    vba.Position<Vector3f>(0) = -(size/3.0f)*Vector3f(1.0f, 1.0f, 1.0f);
    vba.Position<Vector3f>(1) = Vector3f(size, 0.0f, 0.0f);
    vba.Position<Vector3f>(2) = Vector3f(0.0f, size, 0.0f);
    vba.Position<Vector3f>(3) = Vector3f(0.0f, 0.0f, size);

    if (isBlack)
    {
        // Black tetrahedra for the small ones used as points.
        Float3 black(0.0f, 0.0f, 0.0f);
        vba.Color<Float3>(0, 0) = black;
        vba.Color<Float3>(0, 1) = black;
        vba.Color<Float3>(0, 2) = black;
        vba.Color<Float3>(0, 3) = black;
    }
    else
    {
        // Colorful colors for the tetrahedra under study.
        vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 1.0f);
        vba.Color<Float3>(0, 1) = Float3(0.0f, 1.0f, 0.0f);
        vba.Color<Float3>(0, 2) = Float3(1.0f, 0.0f, 0.0f);
        vba.Color<Float3>(0, 3) = Float3(1.0f, 1.0f, 1.0f);
    }

    IndexBuffer* ibuffer = new0 IndexBuffer(12, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[ 0] = 0; indices[ 1] = 2; indices[ 2] = 1;
    indices[ 3] = 0; indices[ 4] = 3; indices[ 5] = 2;
    indices[ 6] = 0; indices[ 7] = 1; indices[ 8] = 3;
    indices[ 9] = 1; indices[10] = 2; indices[11] = 3;

    TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
    mesh->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

    return mesh;
}
Esempio n. 15
0
//----------------------------------------------------------------------------
ClodMesh::ClodMesh (TriMesh* mesh, CollapseRecordArray* recordArray)
:
TriMesh(mesh->GetVertexFormat(), mesh->GetVertexBuffer(), 0),
mCurrentRecord(0),
mTargetRecord(0),
mRecordArray(recordArray)
{
	assertion(recordArray != 0, "Record array is needed for construction.\n");

	// 创建一份顶点索引的拷贝
	IndexBuffer* ibuffer = mesh->GetIndexBuffer();
	int numIndices = ibuffer->GetNumElements();
	int elementSize = ibuffer->GetElementSize();
	assertion(elementSize == 4, "Invalid indices.\n");

	char* srcIndices = ibuffer->GetData();
	mIBuffer = new0 IndexBuffer(numIndices, elementSize);
	char* trgIndices = mIBuffer->GetData();
	memcpy(trgIndices, srcIndices, numIndices*elementSize);
}
Esempio n. 16
0
//----------------------------------------------------------------------------
TriMesh* StandardMesh::Tetrahedron ()
{
    float fSqrt2Div3 = Mathf::Sqrt(2.0f)/3.0f;
    float fSqrt6Div3 = Mathf::Sqrt(6.0f)/3.0f;
    float fOneThird = 1.0f/3.0f;

    int numVertices = 4;
    int numTriangles = 4;
    int numIndices = 3*numTriangles;
    int stride = mVFormat->GetStride();

    // Create a vertex buffer.
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride, mUsage);
    VertexBufferAccessor vba(mVFormat, vbuffer);

    // Generate geometry.
    vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 1.0f);
    vba.Position<Float3>(1) = Float3(2.0f*fSqrt2Div3, 0.0f, -fOneThird);
    vba.Position<Float3>(2) = Float3(-fSqrt2Div3, fSqrt6Div3, -fOneThird);
    vba.Position<Float3>(3) = Float3(-fSqrt2Div3, -fSqrt6Div3, -fOneThird);
    CreatePlatonicNormals(vba);
    CreatePlatonicUVs(vba);
    TransformData(vba);

    // Generate indices.
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage);
    int* indices = (int*)ibuffer->GetData();
    indices[ 0] = 0;  indices[ 1] = 1;  indices[ 2] = 2;
    indices[ 3] = 0;  indices[ 4] = 2;  indices[ 5] = 3;
    indices[ 6] = 0;  indices[ 7] = 3;  indices[ 8] = 1;
    indices[ 9] = 1;  indices[10] = 3;  indices[11] = 2;

    if (mInside)
    {
        ReverseTriangleOrder(numTriangles,indices);
    }

    return new0 TriMesh(mVFormat, vbuffer, ibuffer);
}
Esempio n. 17
0
//----------------------------------------------------------------------------
TriMesh* Delaunay3D::CreateTetra (int index) const
{
    const Vector3f* dvertices = mDelaunay->GetVertices();
    const int* dindices = mDelaunay->GetIndices();

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    vba.Position<Vector3f>(0) = dvertices[dindices[4*index    ]];
    vba.Position<Vector3f>(1) = dvertices[dindices[4*index + 1]];
    vba.Position<Vector3f>(2) = dvertices[dindices[4*index + 2]];
    vba.Position<Vector3f>(3) = dvertices[dindices[4*index + 3]];
    Float4 lightGray(0.75f, 0.75f, 0.75f, 1.0f);
    vba.Color<Float4>(0, 0) = lightGray;
    vba.Color<Float4>(0, 1) = lightGray;
    vba.Color<Float4>(0, 2) = lightGray;
    vba.Color<Float4>(0, 3) = lightGray;

    IndexBuffer* ibuffer = new0 IndexBuffer(12, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[ 0] = 0;  indices[ 1] = 1;  indices[ 2] = 2;
    indices[ 3] = 0;  indices[ 4] = 3;  indices[ 5] = 1;
    indices[ 6] = 0;  indices[ 7] = 2;  indices[ 8] = 3;
    indices[ 9] = 3;  indices[10] = 2;  indices[11] = 1;

    TriMesh* tetra = new0 TriMesh(vformat, vbuffer, ibuffer);
    VisualEffectInstance* instance =
        VertexColor4Effect::CreateUniqueInstance();
    instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true;
    instance->GetEffect()->GetWireState(0, 0)->Enabled = true;
    tetra->SetEffectInstance(instance);

    return tetra;
}
Esempio n. 18
0
//----------------------------------------------------------------------------
IndexBuffer* Visual::LoadIndexBuffer (FileIO& inFile)
{
    int numElements;
    inFile.Read(sizeof(int), &numElements);

    if (numElements > 0)
    {
        int elementSize, usage, offset;
        inFile.Read(sizeof(int), &elementSize);
        inFile.Read(sizeof(int), &usage);
        inFile.Read(sizeof(int), &offset);

        IndexBuffer* ibuffer = new0 IndexBuffer(numElements, elementSize,
                                                (Buffer::Usage)usage);
        ibuffer->SetOffset(offset);

        inFile.Read(elementSize, ibuffer->GetNumBytes()/elementSize,
                    ibuffer->GetData());

        return ibuffer;
    }

    return 0;
}
//----------------------------------------------------------------------------
void ReflectionsAndShadows::CreatePlanes ()
{
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    // Create the floor mesh.
    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor floor(vformat, vbuffer);

    float xValue = 128.0f;
    float yValue = 256.0f;
    float zValue = 0.0f;
    floor.Position<Float3>(0) = Float3(-xValue, -yValue, zValue);
    floor.Position<Float3>(1) = Float3(+xValue, -yValue, zValue);
    floor.Position<Float3>(2) = Float3(+xValue, +yValue, zValue);
    floor.Position<Float3>(3) = Float3(-xValue, +yValue, zValue);
    floor.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    floor.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    floor.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
    floor.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 2;
    indices[3] = 0;  indices[4] = 2;  indices[5] = 3;

    mPlane0 = new0 TriMesh(vformat, vbuffer, ibuffer);

    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR,
        Shader::SC_REPEAT, Shader::SC_REPEAT);
    std::string path = Environment::GetPathR("Sand.wmtf");
    Texture2D* texture = Texture2D::LoadWMTF(path);
    mPlane0->SetEffectInstance(effect->CreateInstance(texture));

    mScene->AttachChild(mPlane0);

    // Create the wall mesh.
    vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor wall(vformat, vbuffer);

    xValue = -128.0f;
    yValue = 256.0f;
    zValue = 128.0f;
    wall.Position<Float3>(0) = Float3(xValue, -yValue, 0.0f);
    wall.Position<Float3>(1) = Float3(xValue, +yValue, 0.0f);
    wall.Position<Float3>(2) = Float3(xValue, +yValue, zValue);
    wall.Position<Float3>(3) = Float3(xValue, -yValue, zValue);
    wall.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    wall.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    wall.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f);
    wall.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f);

    mPlane1 = new0 TriMesh(vformat, vbuffer, ibuffer);

    path = Environment::GetPathR("Stone.wmtf");
    texture = Texture2D::LoadWMTF(path);
    mPlane1->SetEffectInstance(effect->CreateInstance(texture));

    mScene->AttachChild(mPlane1);
}
//----------------------------------------------------------------------------
void IntersectConvexPolyhedra::ComputeIntersection ()
{
    // Transform the model-space vertices to world space.
    VertexBufferAccessor vba(mMeshPoly0);
    int i;
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        APoint modPos = vba.Position<Float3>(i);
        APoint locPos = mMeshPoly0->LocalTransform*modPos;
        mWorldPoly0.Point(i) = Vector3f(locPos[0], locPos[1], locPos[2]);
    }
    mWorldPoly0.UpdatePlanes();

    vba.ApplyTo(mMeshPoly1);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        APoint modPos = vba.Position<Float3>(i);
        APoint locPos = mMeshPoly1->LocalTransform*modPos;
        mWorldPoly1.Point(i) = Vector3f(locPos[0], locPos[1], locPos[2]);
    }
    mWorldPoly1.UpdatePlanes();

    // Compute the intersection (if any) in world space.
    bool hasIntersection = mWorldPoly0.FindIntersection(mWorldPoly1,
        mIntersection);

    if (hasIntersection)
    {
        // Build the corresponding mesh.
        int numVertices = mIntersection.GetNumVertices();
        int numTriangles = mIntersection.GetNumTriangles();
        int numIndices = 3*numTriangles;
        VertexFormat* vformat = mMeshPoly0->GetVertexFormat();
        int vstride = vformat->GetStride();
        VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
        IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
        Float3 green(0.0f, 1.0f, 0.0f);
        vba.ApplyTo(vformat, vbuffer);
        for (i = 0; i < numVertices; ++i)
        {
            vba.Position<Vector3f>(i) = mIntersection.Point(i);
            vba.Color<Float3>(0, i) = green;
        }
        int* indices = (int*)ibuffer->GetData();
        for (i = 0; i < numTriangles; ++i)
        {
            const MTTriangle& triangle = mIntersection.GetTriangle(i);
            for (int j = 0; j < 3; ++j)
            {
                indices[3*i + j] =
                    mIntersection.GetVLabel(triangle.GetVertex(j));
            }
        }

        mMeshIntersection = new0 TriMesh(vformat, vbuffer, ibuffer);
        mMeshIntersection->SetEffectInstance(
            VertexColor3Effect::CreateUniqueInstance());
        mScene->SetChild(0, mMeshIntersection);

        mMeshIntersection->Culling = Spatial::CULL_DYNAMIC;
    }
    else
    {
        mMeshIntersection->Culling = Spatial::CULL_ALWAYS;
    }
}
//----------------------------------------------------------------------------
void IntersectConvexPolyhedra::CreateScene ()
{
    mScene = new0 Node();
    mMotionObject = mScene;

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    // Attach a dummy intersection mesh.  If the intersection is nonempty,
    // the Culling flag will be modified to CULL_DYNAMIC.  The intersection
    // is drawn as a solid.
    mMeshIntersection = StandardMesh(vformat).Tetrahedron();
    VertexBufferAccessor vba(mMeshIntersection);
    Float3 green(0.0f, 1.0f, 0.0f);
    int i, j;
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = green;
    }
    mMeshIntersection->SetEffectInstance(
        VertexColor3Effect::CreateUniqueInstance());
    mMeshIntersection->Culling = Spatial::CULL_ALWAYS;
    mScene->AttachChild(mMeshIntersection);

    // The first polyhedron is an ellipsoid.
    ConvexPolyhedronf::CreateEggShape(Vector3f::ZERO, 1.0f, 1.0f, 2.0f, 2.0f,
        4.0f, 4.0f, 3, mWorldPoly0);

    // Build the corresponding mesh.
    int numVertices = mWorldPoly0.GetNumVertices();
    int numTriangles = mWorldPoly0.GetNumTriangles();
    int numIndices = 3*numTriangles;
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    Float3 red(1.0f, 0.0f, 0.0f);
    vba.ApplyTo(vformat, vbuffer);
    for (i = 0; i < numVertices; ++i)
    {
        vba.Position<Vector3f>(i) = mWorldPoly0.Point(i);
        vba.Color<Float3>(0,i) = red;
    }
    int* indices = (int*)ibuffer->GetData();
    for (i = 0; i < numTriangles; ++i)
    {
        const MTTriangle& triangle = mWorldPoly0.GetTriangle(i);
        for (j = 0; j < 3; ++j)
        {
            indices[3*i + j] = mWorldPoly0.GetVLabel(triangle.GetVertex(j));
        }
    }

    mMeshPoly0 = new0 TriMesh(vformat, vbuffer, ibuffer);
    VisualEffectInstance* instance =
        VertexColor3Effect::CreateUniqueInstance();
    instance->GetEffect()->GetWireState(0, 0)->Enabled = true;
    mMeshPoly0->SetEffectInstance(instance);
    mMeshPoly0->LocalTransform.SetTranslate(APoint(0.0f, 2.0f, 0.0f));
    mScene->AttachChild(mMeshPoly0);

    // The second polyhedron is egg shaped.
    ConvexPolyhedronf::CreateEggShape(Vector3f::ZERO, 2.0f, 2.0f, 4.0f, 4.0f,
        5.0f, 3.0f, 4, mWorldPoly1);

    // Build the corresponding mesh.
    numVertices = mWorldPoly1.GetNumVertices();
    numTriangles = mWorldPoly1.GetNumTriangles();
    numIndices = 3*numTriangles;
    vbuffer = new0 VertexBuffer(numVertices, vstride);
    ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    Float3 blue(0.0f, 0.0f, 1.0f);
    vba.ApplyTo(vformat, vbuffer);
    for (i = 0; i < numVertices; ++i)
    {
        vba.Position<Vector3f>(i) = mWorldPoly1.Point(i);
        vba.Color<Float3>(0, i) = blue;
    }
    indices = (int*)ibuffer->GetData();
    for (i = 0; i < numTriangles; ++i)
    {
        const MTTriangle& triangle = mWorldPoly1.GetTriangle(i);
        for (j = 0; j < 3; ++j)
        {
            indices[3*i + j] = mWorldPoly1.GetVLabel(triangle.GetVertex(j));
        }
    }

    mMeshPoly1 = new0 TriMesh(vformat, vbuffer, ibuffer);
    instance = VertexColor3Effect::CreateUniqueInstance();
    instance->GetEffect()->GetWireState(0, 0)->Enabled = true;
    mMeshPoly1->SetEffectInstance(instance);
    mMeshPoly1->LocalTransform.SetTranslate(APoint(0.0f, -2.0f, 0.0f));
    mScene->AttachChild(mMeshPoly1);

    ComputeIntersection();
}
Esempio n. 22
0
//----------------------------------------------------------------------------
TriMesh* StandardMesh::Cylinder (int axisSamples, int radialSamples,
    float radius, float height, bool open)
{
    TriMesh* mesh;
    int unit;
    Float2 tcoord;

    if (open)
    {
        int numVertices = axisSamples*(radialSamples+1);
        int numTriangles = 2*(axisSamples-1)*radialSamples;
        int numIndices = 3*numTriangles;
        int stride = mVFormat->GetStride();

        // Create a vertex buffer.
        VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride,
            mUsage);

        VertexBufferAccessor vba(mVFormat, vbuffer);

        // Generate geometry.
        float invRS = 1.0f/(float)radialSamples;
        float invASm1 = 1.0f/(float)(axisSamples-1);
        float halfHeight = 0.5f*height;
        int r, a, aStart, i;

        // Generate points on the unit circle to be used in computing the
        // mesh points on a cylinder slice.
        float* cs = new1<float>(radialSamples + 1);
        float* sn = new1<float>(radialSamples + 1);
        for (r = 0; r < radialSamples; ++r)
        {
            float angle = Mathf::TWO_PI*invRS*r;
            cs[r] = Mathf::Cos(angle);
            sn[r] = Mathf::Sin(angle);
        }
        cs[radialSamples] = cs[0];
        sn[radialSamples] = sn[0];

        // Generate the cylinder itself.
        for (a = 0, i = 0; a < axisSamples; ++a)
        {
            float axisFraction = a*invASm1;  // in [0,1]
            float z = -halfHeight + height*axisFraction;

            // Compute center of slice.
            APoint sliceCenter(0.0f, 0.0f, z);

            // Compute slice vertices with duplication at endpoint.
            int save = i;
            for (r = 0; r < radialSamples; ++r)
            {
                float radialFraction = r*invRS;  // in [0,1)
                AVector normal(cs[r], sn[r], 0.0f);

                vba.Position<Float3>(i) = sliceCenter + radius*normal;

                if (mHasNormals)
                {
                    if (mInside)
                    {
                        vba.Normal<Float3>(i) = -normal;
                    }
                    else
                    {
                        vba.Normal<Float3>(i) = normal;
                    }
                }

                tcoord = Float2(radialFraction, axisFraction);
                for (unit = 0; unit < MAX_UNITS; ++unit)
                {
                    if (mHasTCoords[unit])
                    {
                        vba.TCoord<Float2>(unit, i) = tcoord;
                    }
                }

                ++i;
            }

            vba.Position<Float3>(i) = vba.Position<Float3>(save);

            if (mHasNormals)
            {
                vba.Normal<Float3>(i) = vba.Normal<Float3>(save);
            }

            tcoord = Float2(1.0f, axisFraction);
            for (unit = 0; unit < MAX_UNITS; ++unit)
            {
                if (mHasTCoords[unit])
                {
                    vba.TCoord<Float2>(0, i) = tcoord;
                }
            }

            ++i;
        }
        TransformData(vba);

        // Generate indices.
        IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage);
        int* indices = (int*)ibuffer->GetData();
        for (a = 0, aStart = 0; a < axisSamples-1; ++a)
        {
            int i0 = aStart;
            int i1 = i0 + 1;
            aStart += radialSamples + 1;
            int i2 = aStart;
            int i3 = i2 + 1;
            for (i = 0; i < radialSamples; ++i, indices += 6)
            {
                if (mInside)
                {
                    indices[0] = i0++;
                    indices[1] = i2;
                    indices[2] = i1;
                    indices[3] = i1++;
                    indices[4] = i2++;
                    indices[5] = i3++;
                }
                else // outside view
                {
                    indices[0] = i0++;
                    indices[1] = i1;
                    indices[2] = i2;
                    indices[3] = i1++;
                    indices[4] = i3++;
                    indices[5] = i2++;
                }
            }
        }

        delete1(cs);
        delete1(sn);

        mesh = new0 TriMesh(mVFormat, vbuffer, ibuffer);
    }
    else
    {
        mesh = Sphere(axisSamples, radialSamples, radius);
        VertexBuffer* vbuffer = mesh->GetVertexBuffer();
        int numVertices = vbuffer->GetNumElements();

        VertexBufferAccessor vba(mVFormat, vbuffer);

        // Flatten sphere at poles.
        float hDiv2 = 0.5f*height;
        vba.Position<Float3>(numVertices-2)[2] = -hDiv2;  // south pole
        vba.Position<Float3>(numVertices-1)[2] = +hDiv2;  // north pole

        // Remap z-values to [-h/2,h/2].
        float zFactor = 2.0f/(axisSamples-1);
        float tmp0 = radius*(-1.0f + zFactor);
        float tmp1 = 1.0f/(radius*(+1.0f - zFactor));
        for (int i = 0; i < numVertices-2; ++i)
        {
            Float3& pos = vba.Position<Float3>(i);
            pos[2] = hDiv2*(-1.0f + tmp1*(pos[2] - tmp0));
            float adjust = radius*Mathf::InvSqrt(pos[0]*pos[0] +
                pos[1]*pos[1]);
            pos[0] *= adjust;
            pos[1] *= adjust;
        }
        TransformData(vba);

        if (mHasNormals)
        {
            mesh->UpdateModelSpace(Visual::GU_NORMALS);
        }
    }

    // The duplication of vertices at the seam causes the automatically
    // generated bounding volume to be slightly off center.  Reset the bound
    // to use the true information.
    float maxDist = Mathf::Sqrt(radius*radius + height*height);
    mesh->GetModelBound().SetCenter(APoint::ORIGIN);
    mesh->GetModelBound().SetRadius(maxDist);
    return mesh;
}
Esempio n. 23
0
//----------------------------------------------------------------------------
TriMesh* StandardMesh::Sphere (int zSamples, int radialSamples,
    float radius)
{
    int zsm1 = zSamples-1, zsm2 = zSamples-2, zsm3 = zSamples-3;
    int rsp1 = radialSamples+1;
    int numVertices = zsm2*rsp1 + 2;
    int numTriangles = 2*zsm2*radialSamples;
    int numIndices = 3*numTriangles;
    int stride = mVFormat->GetStride();

    // Create a vertex buffer.
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride, mUsage);
    VertexBufferAccessor vba(mVFormat, vbuffer);

    // Generate geometry.
    float invRS = 1.0f/(float)radialSamples;
    float zFactor = 2.0f/(float)zsm1;
    int r, z, zStart, i, unit;
    Float2 tcoord;

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    float* sn = new1<float>(rsp1);
    float* cs = new1<float>(rsp1);
    for (r = 0; r < radialSamples; ++r)
    {
        float angle = Mathf::TWO_PI*invRS*r;
        cs[r] = Mathf::Cos(angle);
        sn[r] = Mathf::Sin(angle);
    }
    sn[radialSamples] = sn[0];
    cs[radialSamples] = cs[0];

    // Generate the cylinder itself.
    for (z = 1, i = 0; z < zsm1; ++z)
    {
        float zFraction = -1.0f + zFactor*z;  // in (-1,1)
        float zValue = radius*zFraction;

        // Compute center of slice.
        APoint sliceCenter(0.0f, 0.0f, zValue);

        // Compute radius of slice.
        float sliceRadius = Mathf::Sqrt(Mathf::FAbs(
            radius*radius - zValue*zValue));

        // Compute slice vertices with duplication at endpoint.
        AVector normal;
        int save = i;
        for (r = 0; r < radialSamples; ++r)
        {
            float radialFraction = r*invRS;  // in [0,1)
            AVector radial(cs[r], sn[r], 0.0f);

            vba.Position<Float3>(i) = sliceCenter + sliceRadius*radial;

            if (mHasNormals)
            {
                normal = vba.Position<Float3>(i);
                normal.Normalize();
                if (mInside)
                {
                    vba.Normal<Float3>(i) = -normal;
                }
                else
                {
                    vba.Normal<Float3>(i) = normal;
                }
            }

            tcoord[0] = radialFraction;
            tcoord[1] = 0.5f*(zFraction + 1.0f);
            for (unit = 0; unit < MAX_UNITS; ++unit)
            {
                if (mHasTCoords[unit])
                {
                    vba.TCoord<Float2>(unit, i) = tcoord;
                }
            }

            ++i;
        }

        vba.Position<Float3>(i) = vba.Position<Float3>(save);
        if (mHasNormals)
        {
            vba.Normal<Float3>(i) = vba.Normal<Float3>(save);
        }

        tcoord[0] = 1.0f;
        tcoord[1] = 0.5f*(zFraction + 1.0f);
        for (unit = 0; unit < MAX_UNITS; ++unit)
        {
            if (mHasTCoords[unit])
            {
                vba.TCoord<Float2>(unit, i) = tcoord;
            }
        }

        ++i;
    }

    // south pole
    vba.Position<Float3>(i) = Float3(0.0f, 0.0f, -radius);
    if (mHasNormals)
    {
        if (mInside)
        {
            vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, 1.0f);
        }
        else
        {
            vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, -1.0f);
        }
    }

    tcoord = Float2(0.5f, 0.5f);
    for (unit = 0; unit < MAX_UNITS; ++unit)
    {
        if (mHasTCoords[unit])
        {
            vba.TCoord<Float2>(unit, i) = tcoord;
        }
    }

    ++i;

    // north pole
    vba.Position<Float3>(i) = Float3(0.0f, 0.0f, radius);
    if (mHasNormals)
    {
        if (mInside)
        {
            vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, -1.0f);
        }
        else
        {
            vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, 1.0f);
        }
    }

    tcoord = Float2(0.5f, 1.0f);
    for (unit = 0; unit < MAX_UNITS; ++unit)
    {
        if (mHasTCoords[unit])
        {
            vba.TCoord<Float2>(unit, i) = tcoord;
        }
    }

    ++i;

    TransformData(vba);

    // Generate indices.
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage);
    int* indices = (int*)ibuffer->GetData();
    for (z = 0, zStart = 0; z < zsm3; ++z)
    {
        int i0 = zStart;
        int i1 = i0 + 1;
        zStart += rsp1;
        int i2 = zStart;
        int i3 = i2 + 1;
        for (i = 0; i < radialSamples; ++i, indices += 6)
        {
            if (mInside)
            {
                indices[0] = i0++;
                indices[1] = i2;
                indices[2] = i1;
                indices[3] = i1++;
                indices[4] = i2++;
                indices[5] = i3++;
            }
            else  // inside view
            {
                indices[0] = i0++;
                indices[1] = i1;
                indices[2] = i2;
                indices[3] = i1++;
                indices[4] = i3++;
                indices[5] = i2++;
            }
        }
    }

    // south pole triangles
    int numVerticesM2 = numVertices - 2;
    for (i = 0; i < radialSamples; ++i, indices += 3)
    {
        if (mInside)
        {
            indices[0] = i;
            indices[1] = i + 1;
            indices[2] = numVerticesM2;
        }
        else
        {
            indices[0] = i;
            indices[1] = numVerticesM2;
            indices[2] = i + 1;
        }
    }

    // north pole triangles
    int numVerticesM1 = numVertices-1, offset = zsm3*rsp1;
    for (i = 0; i < radialSamples; ++i, indices += 3)
    {
        if (mInside)
        {
            indices[0] = i + offset;
            indices[1] = numVerticesM1;
            indices[2] = i + 1 + offset;
        }
        else
        {
            indices[0] = i + offset;
            indices[1] = i + 1 + offset;
            indices[2] = numVerticesM1;
        }
    }

    delete1(cs);
    delete1(sn);

    // The duplication of vertices at the seam cause the automatically
    // generated bounding volume to be slightly off center.  Reset the bound
    // to use the true information.
    TriMesh* mesh = new0 TriMesh(mVFormat, vbuffer, ibuffer);
    mesh->GetModelBound().SetCenter(APoint::ORIGIN);
    mesh->GetModelBound().SetRadius(radius);
    return mesh;
}
Esempio n. 24
0
//----------------------------------------------------------------------------
void Skinning::CreateScene ()
{
    mScene = new0 Node();
    mTrnNode = new0 Node();
    mScene->AttachChild(mTrnNode);

    // The skinned object is a cylinder.
    const int radialSamples = 10;
    const int axisSamples = 7;
    const float radius = 10.0f;
    const float height = 80.0f;
    const float invRS = 1.0f/(float)radialSamples;
    const float invASm1 = 1.0f/(float)(axisSamples - 1);
    const float halfHeight = 0.5f*height;
    const APoint center(0.0f, 0.0f, 100.0f);
    const AVector u(0.0f,0.0f,-1.0f);
    const AVector v(0.0f,1.0f,0.0f);
    const AVector axis(1.0f,0.0f,0.0f);

    // Generate geometry.
    VertexFormat* vformat = VertexFormat::Create(3,
                            VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
                            VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0,
                            VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT4, 0);
    int vstride = vformat->GetStride();
    const int numVertices = axisSamples*(radialSamples + 1);
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    int r, a, aStart, i;
    float* sn = new1<float>(radialSamples + 1);
    float* cs = new1<float>(radialSamples + 1);
    for (r = 0; r < radialSamples; ++r)
    {
        float angle = Mathf::TWO_PI*invRS*r;
        cs[r] = Mathf::Cos(angle);
        sn[r] = Mathf::Sin(angle);
    }
    sn[radialSamples] = sn[0];
    cs[radialSamples] = cs[0];

    // Generate the cylinder itself.
    for (a = 0, i = 0; a < axisSamples; ++a, ++i)
    {
        float axisFraction = a*invASm1;  // in [0,1]
        float z = -halfHeight + height*axisFraction;

        // Compute center of slice.
        APoint sliceCenter = center + z*axis;

        // Compute slice vertices with duplication at end point.
        Float3 color(axisFraction, 1.0f - axisFraction, 0.3f);
        Float4 tcoord;
        int save = i;
        for (r = 0; r < radialSamples; ++r, ++i)
        {
            AVector normal = cs[r]*u + sn[r]*v;
            vba.Position<Float3>(i) = sliceCenter + radius*normal;
            vba.Color<Float3>(0,i) = color;
            vba.TCoord<Float4>(0, i) = ComputeWeights(a);
        }

        vba.Position<Float3>(i) = vba.Position<Float3>(save);
        vba.Color<Float3>(0, i) = color;
        vba.TCoord<Float4>(0, i) = ComputeWeights(a);
    }

    // Generate connectivity.
    int numTriangles = 2*(axisSamples - 1)*radialSamples;
    int numIndices = 3*numTriangles;
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    for (a = 0, aStart = 0; a < axisSamples - 1; ++a)
    {
        int i0 = aStart;
        int i1 = i0 + 1;
        aStart += radialSamples + 1;
        int i2 = aStart;
        int i3 = i2 + 1;
        for (i = 0; i < radialSamples; ++i, indices += 6)
        {
            indices[0] = i0++;
            indices[1] = i1;
            indices[2] = i2;
            indices[3] = i1++;
            indices[4] = i3++;
            indices[5] = i2++;
        }
    }

    delete1(cs);
    delete1(sn);

    TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
    mTrnNode->AttachChild(mesh);

    std::string effectFile = Environment::GetPathR("Skinning.wmfx");
    SkinningEffect* effect = new0 SkinningEffect(effectFile);

    ShaderFloat* skinningMatrix[4] =
    {
        new0 ShaderFloat(4),
        new0 ShaderFloat(4),
        new0 ShaderFloat(4),
        new0 ShaderFloat(4)
    };

    for (i = 0; i < 4; ++i)
    {
        mSkinningMatrix[i] = skinningMatrix[i]->GetData();
    }

    mesh->SetEffectInstance(effect->CreateInstance(skinningMatrix));
}
Esempio n. 25
0
//----------------------------------------------------------------------------
TriMesh* StandardMesh::Torus (int circleSamples, int radialSamples,
    float outerRadius, float innerRadius)
{
    int numVertices = (circleSamples+1)*(radialSamples+1);
    int numTriangles = 2*circleSamples*radialSamples;
    int numIndices = 3*numTriangles;
    int stride = mVFormat->GetStride();

    // Create a vertex buffer.
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride, mUsage);
    VertexBufferAccessor vba(mVFormat, vbuffer);

    // Generate geometry.
    float invCS = 1.0f/(float)circleSamples;
    float invRS = 1.0f/(float)radialSamples;
    int c, r, i, unit;
    Float2 tcoord;

    // Generate the cylinder itself.
    for (c = 0, i = 0; c < circleSamples; ++c)
    {
        // Compute center point on torus circle at specified angle.
        float circleFraction = c*invCS;  // in [0,1)
        float theta = Mathf::TWO_PI*circleFraction;
        float cosTheta = Mathf::Cos(theta);
        float sinTheta = Mathf::Sin(theta);
        AVector radial(cosTheta, sinTheta, 0.0f);
        AVector torusMiddle = outerRadius*radial;

        // Compute slice vertices with duplication at endpoint.
        int save = i;
        for (r = 0; r < radialSamples; ++r)
        {
            float radialFraction = r*invRS;  // in [0,1)
            float phi = Mathf::TWO_PI*radialFraction;
            float cosPhi = Mathf::Cos(phi);
            float sinPhi = Mathf::Sin(phi);
            AVector normal = cosPhi*radial + sinPhi*AVector::UNIT_Z;
            vba.Position<Float3>(i) = torusMiddle + innerRadius*normal;
            if (mHasNormals)
            {
                if (mInside)
                {
                    vba.Normal<Float3>(i) = -normal;
                }
                else
                {
                    vba.Normal<Float3>(i) = normal;
                }
            }

            tcoord = Float2(radialFraction, circleFraction);
            for (unit = 0; unit < MAX_UNITS; ++unit)
            {
                if (mHasTCoords[unit])
                {
                    vba.TCoord<Float2>(unit, i) = tcoord;
                }
            }

            ++i;
        }

        vba.Position<Float3>(i) = vba.Position<Float3>(save);
        if (mHasNormals)
        {
            vba.Normal<Float3>(i) = vba.Normal<Float3>(save);
        }

        tcoord = Float2(1.0f, circleFraction);
        for (unit = 0; unit < MAX_UNITS; ++unit)
        {
            if (mHasTCoords[unit])
            {
                vba.TCoord<Float2>(unit, i) = tcoord;
            }
        }

        ++i;
    }

    // Duplicate the cylinder ends to form a torus.
    for (r = 0; r <= radialSamples; ++r, ++i)
    {
        vba.Position<Float3>(i) = vba.Position<Float3>(r);
        if (mHasNormals)
        {
            vba.Normal<Float3>(i) = vba.Normal<Float3>(r);
        }

        for (unit = 0; unit < MAX_UNITS; ++unit)
        {
            if (mHasTCoords[unit])
            {
                vba.TCoord<Float2>(unit, i) =
                    Float2(vba.TCoord<Float2>(unit, r)[0], 1.0f);
            }
        }
    }

    TransformData(vba);

    // Generate indices.
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage);
    int* indices = (int*)ibuffer->GetData();
    int cStart = 0;
    for (c = 0; c < circleSamples; ++c)
    {
        int i0 = cStart;
        int i1 = i0 + 1;
        cStart += radialSamples + 1;
        int i2 = cStart;
        int i3 = i2 + 1;
        for (i = 0; i < radialSamples; ++i, indices += 6)
        {
            if (mInside)
            {
                indices[0] = i0++;
                indices[1] = i1;
                indices[2] = i2;
                indices[3] = i1++;
                indices[4] = i3++;
                indices[5] = i2++;
            }
            else  // inside view
            {
                indices[0] = i0++;
                indices[1] = i2;
                indices[2] = i1;
                indices[3] = i1++;
                indices[4] = i2++;
                indices[5] = i3++;
            }
        }
    }

    // The duplication of vertices at the seam cause the automatically
    // generated bounding volume to be slightly off center.  Reset the bound
    // to use the true information.
    TriMesh* mesh = new0 TriMesh(mVFormat, vbuffer, ibuffer);
    mesh->GetModelBound().SetCenter(APoint::ORIGIN);
    mesh->GetModelBound().SetRadius(outerRadius);
    return mesh;
}
Esempio n. 26
0
//----------------------------------------------------------------------------
TriMesh* StandardMesh::Rectangle (int xSamples, int ySamples, float xExtent,
    float yExtent)
{
    int numVertices = xSamples*ySamples;
    int numTriangles = 2*(xSamples-1)*(ySamples-1);
    int numIndices = 3*numTriangles;
    int stride = mVFormat->GetStride();

    // Create a vertex buffer.
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride, mUsage);
    VertexBufferAccessor vba(mVFormat, vbuffer);

    // Generate geometry.
    float inv0 = 1.0f/(xSamples - 1.0f);
    float inv1 = 1.0f/(ySamples - 1.0f);
    float u, v, x, y;
    int i, i0, i1;
    for (i1 = 0, i = 0; i1 < ySamples; ++i1)
    {
        v = i1*inv1;
        y = (2.0f*v - 1.0f)*yExtent;
        for (i0 = 0; i0 < xSamples; ++i0, ++i)
        {
            u = i0*inv0;
            x = (2.0f*u - 1.0f)*xExtent;

            vba.Position<Float3>(i) = Float3(x, y, 0.0f);

            if (mHasNormals)
            {
                vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, 1.0f);
            }

            Float2 tcoord(u, v);
            for (int unit = 0; unit < MAX_UNITS; ++unit)
            {
                if (mHasTCoords[unit])
                {
                    vba.TCoord<Float2>(unit, i) = tcoord;
                }
            }
        }
    }
    TransformData(vba);

    // Generate indices.
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage);
    int* indices = (int*)ibuffer->GetData();
    for (i1 = 0; i1 < ySamples - 1; ++i1)
    {
        for (i0 = 0; i0 < xSamples - 1; ++i0)
        {
            int v0 = i0 + xSamples * i1;
            int v1 = v0 + 1;
            int v2 = v1 + xSamples;
            int v3 = v0 + xSamples;
            *indices++ = v0;
            *indices++ = v1;
            *indices++ = v2;
            *indices++ = v0;
            *indices++ = v2;
            *indices++ = v3;
        }
    }

    return new0 TriMesh(mVFormat, vbuffer, ibuffer);
}
Esempio n. 27
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);
	}
}
Esempio n. 28
0
//----------------------------------------------------------------------------
void CubeMaps::CreateScene ()
{
    // Create the root of the scene.
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Create the walls of the cube room.  Each of the six texture images is
    // RGBA 64-by-64.
    Node* room = new0 Node();
    mScene->AttachChild(room);

    // Index buffer shared by the room walls.
    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 3;
    indices[3] = 0;  indices[4] = 3;  indices[5] = 2;

    // The vertex format shared by the room walls.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();
    VertexBufferAccessor vba;

    // The texture effect shared by the room walls.
    Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);

    VertexBuffer* vbuffer;
    TriMesh* wall;
    std::string textureName;

    // +x wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f);
    vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, +1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("XpFace.wmtf");
    Texture2D* xpTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(xpTexture));

    // -x wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("XmFace.wmtf");
    Texture2D* xmTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(xmTexture));

    // +y wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("YpFace.wmtf");
    Texture2D* ypTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(ypTexture));

    // -y wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, -1.0f, +1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("YmFace.wmtf");
    Texture2D* ymTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(ymTexture));

    // +z wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, +1.0f);
    vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, +1.0f);
    vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, +1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("ZpFace.wmtf");
    Texture2D* zpTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(zpTexture));

    // -z wall
    vbuffer = new0 VertexBuffer(4, vstride);
    vba.ApplyTo(vformat, vbuffer);
    vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, -1.0f);
    vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, -1.0f);
    vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, -1.0f);
    vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
    wall = new0 TriMesh(vformat, vbuffer, ibuffer);
    room->AttachChild(wall);
    textureName = Environment::GetPathR("ZmFace.wmtf");
    Texture2D* zmTexture = Texture2D::LoadWMTF(textureName);
    wall->SetEffectInstance(effect->CreateInstance(zmTexture));

    // A sphere to reflect the environment via a cube map.  The colors will
    // be used to modulate the cube map texture.
    vformat = VertexFormat::Create(3,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    vstride = vformat->GetStride();

    mSphere = StandardMesh(vformat).Sphere(64, 64, 0.125f);
    room->AttachChild(mSphere);

    // Generate random vertex colors for the sphere.  The StandardMesh class
    // produces a sphere with duplicated vertices along a longitude line.
    // This allows texture coordinates to be assigned in a manner that treats
    // the sphere as if it were a rectangle mesh.  For vertex colors, we want
    // the duplicated vertices to have the same color, so a hash table is used
    // to look up vertex colors for the duplicates.
    vba.ApplyTo(mSphere);
    std::map<Float3,Float3> dataMap;
    for (int i = 0; i < vba.GetNumVertices(); ++i)
    {
        Float3& position = vba.Position<Float3>(i);
        Float3& color = vba.Color<Float3>(0, i);
        std::map<Float3,Float3>::iterator iter = dataMap.find(position);
        if (iter != dataMap.end())
        {
            color = iter->second;
        }
        else
        {
            color[0] = 0.0f;
            color[1] = Mathf::IntervalRandom(0.5f, 0.75f);
            color[2] = Mathf::IntervalRandom(0.75f, 1.0f);
            dataMap.insert(std::make_pair(position, color));
        }
    }

    // Create the cube map and attach it to the sphere.
    std::string effectFile = Environment::GetPathR("CubeMap.wmfx");
    CubeMapEffect* cubeMapEffect = new0 CubeMapEffect(effectFile);

    ShaderFloat* reflectivity = new0 ShaderFloat(1);
    (*reflectivity)[0] = 0.5f;

    std::string cubeName = Environment::GetPathR("CubeMap.wmtf");
    TextureCube* cubeTexture = TextureCube::LoadWMTF(cubeName);
    cubeTexture->GenerateMipmaps();
    mCubeMapInstance = cubeMapEffect->CreateInstance(cubeTexture,
        reflectivity, false);

    mSphere->SetEffectInstance(mCubeMapInstance);

    // Allow culling to be disabled on the sphere so when you move inside
    // the sphere, you can see the previously hidden facets and verify that
    // the cube image for those facets is correctly oriented.
    mSphereCullState = cubeMapEffect->GetCullState(0, 0);
}
Esempio n. 29
0
//----------------------------------------------------------------------------
void GlossMaps::CreateScene ()
{
    mScene = new0 Node();
    mTrnNode = new0 Node();
    mScene->AttachChild(mTrnNode);

    // Create vertex and index buffers to be shared by two meshes.
    VertexFormat* vformat = VertexFormat::Create(3,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
    int vstride = vformat->GetStride();

    VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    Float3 yVector(0.0f, 1.0f, 0.0f);
    vba.Position<Float3>(0) = Float3(-0.5f, 0.0f, -0.5f);
    vba.Position<Float3>(1) = Float3(-0.5f, 0.0f,  0.5f);
    vba.Position<Float3>(2) = Float3( 0.5f, 0.0f,  0.5f);
    vba.Position<Float3>(3) = Float3( 0.5f, 0.0f, -0.5f);
    vba.Normal<Float3>(0) = yVector;
    vba.Normal<Float3>(1) = yVector;
    vba.Normal<Float3>(2) = yVector;
    vba.Normal<Float3>(3) = yVector;
    vba.TCoord<Float2>(0, 0) = Float2(1.0f, 0.0f);
    vba.TCoord<Float2>(0, 1) = Float2(1.0f, 1.0f);
    vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
    vba.TCoord<Float2>(0, 3) = Float2(0.0f, 0.0f);

    IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    indices[0] = 0;  indices[1] = 1;  indices[2] = 3;
    indices[3] = 3;  indices[4] = 1;  indices[5] = 2;

    // The light and material are used by both the gloss and non-gloss
    // objects.
    Light* light = new0 Light(Light::LT_DIRECTIONAL);
    light->Ambient = Float4(0.1f, 0.1f, 0.1f, 1.0f);
    light->Diffuse = Float4(0.6f, 0.6f, 0.6f, 1.0f);
    light->Specular = Float4(1.0f, 1.0f, 1.0f, 1.0f);
    light->DVector = AVector(0.0f, -1.0f, 0.0f);

    Material* material = new0 Material();
    material->Ambient = Float4(0.2f, 0.2f, 0.2f, 1.0f);
    material->Diffuse = Float4(0.7f, 0.7f, 0.7f, 1.0f);
    material->Specular = Float4(1.0f, 1.0f, 1.0f, 25.0f);

    // Create a non-gloss-mapped square.
    TriMesh* squareNoGloss = new0 TriMesh(vformat, vbuffer, ibuffer);
    squareNoGloss->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X,
        -0.25f*Mathf::PI));
    squareNoGloss->LocalTransform.SetTranslate(APoint(1.0f, -1.0f, 0.0f));
    squareNoGloss->SetEffectInstance(
        LightDirPerVerEffect::CreateUniqueInstance(light, material));
    mTrnNode->AttachChild(squareNoGloss);

    // Create a gloss-mapped square.
    TriMesh* squareGloss = new0 TriMesh(vformat, vbuffer, ibuffer);
    squareGloss->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X,
        -0.25f*Mathf::PI));
    squareGloss->LocalTransform.SetTranslate(APoint(-1.0f, -1.0f, 0.0f));
    mTrnNode->AttachChild(squareGloss);

    std::string effectFile = Environment::GetPathR("GlossMap.wmfx");
    GlossMapEffect* effect = new0 GlossMapEffect(effectFile);

    std::string baseName = Environment::GetPathR("Magic.wmtf");
    Texture2D* baseTexture = Texture2D::LoadWMTF(baseName);
    squareGloss->SetEffectInstance(effect->CreateInstance(baseTexture,
        light, material));
}
Esempio n. 30
0
//----------------------------------------------------------------------------
TriMesh* Castle::LoadMeshPNT2 (const std::string& name)
{
    // Get the vertex format.
    VertexFormat* vformat = VertexFormat::Create(4,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0,
        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 1);
    int vstride = vformat->GetStride();

    // Get the positions.
    std::string filename = Environment::GetPathR(name);
    std::ifstream inFile(filename.c_str());
    int numPositions;
    Float3* positions;
    GetFloat3(inFile, numPositions, positions);

    // Get the normals.
    int numNormals;
    Float3* normals;
    GetFloat3(inFile, numNormals, normals);

    // Get the texture coordinates for unit 0.
    int numTCoords0;
    Float2* tcoords0;
    GetFloat2(inFile, numTCoords0, tcoords0);

    // Get the texture coordinates for unit 1.
    int numTCoords1;
    Float2* tcoords1;
    GetFloat2(inFile, numTCoords1, tcoords1);

    // Get the vertices and indices.
    int numTriangles;
    inFile >> numTriangles;
    VertexPNT2* vertices = new1<VertexPNT2>(3*numTriangles);
    std::vector<VertexPNT2> PNT2Array;
    std::map<VertexPNT2,int> PNT2Map;
    std::vector<int> indices;
    for (int t = 0; t < numTriangles; ++t)
    {
        for (int j = 0, k = 3*t; j < 3; ++j, ++k)
        {
            VertexPNT2& vertex = vertices[k];
            inFile >> vertex.PIndex;
            inFile >> vertex.NIndex;
            inFile >> vertex.T0Index;
            inFile >> vertex.T1Index;

            std::map<VertexPNT2,int>::iterator miter = PNT2Map.find(vertex);
            int index;
            if (miter != PNT2Map.end())
            {
                // Second or later time the vertex is encountered.
                index = miter->second;
            }
            else
            {
                // First time the vertex is encountered.
                index = (int)PNT2Array.size();
                PNT2Map.insert(std::make_pair(vertex, index));
                PNT2Array.push_back(vertex);
            }
            indices.push_back(index);
        }
    }
    inFile.close();

    // Build the mesh.
    int numVertices = (int)PNT2Array.size();
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);
    for (int i = 0; i < numVertices; ++i)
    {
        VertexPNT2& vertex = PNT2Array[i];
        vba.Position<Float3>(i) = positions[vertex.PIndex];
        vba.Normal<Float3>(i) = normals[vertex.NIndex];
        vba.TCoord<Float2>(0, i) = tcoords0[vertex.T0Index];
        vba.TCoord<Float2>(1, i) = tcoords1[vertex.T1Index];
    }

    int numIndices = (int)indices.size();
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    memcpy(ibuffer->GetData(), &indices[0], numIndices*sizeof(int));

    delete1(vertices);
    delete1(tcoords1);
    delete1(tcoords0);
    delete1(normals);
    delete1(positions);

    return new0 TriMesh(vformat, vbuffer, ibuffer);
}