//---------------------------------------------------------------------------- void CollisionsBoundTree::Response (CRecord& record0, int t0, CRecord& record1, int t1, Intersector<float,Vector3f>*) { CollisionsBoundTree* app = (CollisionsBoundTree*)TheApplication; // Mesh0 triangles that are intersecting change from blue to cyan. TriMesh* mesh = record0.GetMesh(); VertexBufferAccessor vba(mesh); const int* indices = (int*)mesh->GetIndexBuffer()->GetData(); int i0 = indices[3*t0]; int i1 = indices[3*t0 + 1]; int i2 = indices[3*t0 + 2]; vba.TCoord<Float2>(0, i0) = app->mCyanUV; vba.TCoord<Float2>(0, i1) = app->mCyanUV; vba.TCoord<Float2>(0, i2) = app->mCyanUV; app->mRenderer->Update(mesh->GetVertexBuffer()); // Mesh1 triangles that are intersecting change from red to yellow. mesh = record1.GetMesh(); vba.ApplyTo(mesh); indices = (int*)mesh->GetIndexBuffer()->GetData(); i0 = indices[3*t1]; i1 = indices[3*t1 + 1]; i2 = indices[3*t1 + 2]; vba.TCoord<Float2>(0 ,i0) = app->mYellowUV; vba.TCoord<Float2>(0, i1) = app->mYellowUV; vba.TCoord<Float2>(0, i2) = app->mYellowUV; app->mRenderer->Update(mesh->GetVertexBuffer()); // NOTE: See the comments in Wm5CollisionGroup.h about information that // is available from the Intersector<float,Vector3f> object. }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- void IntersectingBoxes::ModifyMesh (int i) { Vector3f center( 0.5f*(mBoxes[i].Min[0] + mBoxes[i].Max[0]), 0.5f*(mBoxes[i].Min[1] + mBoxes[i].Max[1]), 0.5f*(mBoxes[i].Min[2] + mBoxes[i].Max[2])); float xExtent = 0.5f*(mBoxes[i].Max[0] - mBoxes[i].Min[0]); float yExtent = 0.5f*(mBoxes[i].Max[1] - mBoxes[i].Min[1]); float zExtent = 0.5f*(mBoxes[i].Max[2] - mBoxes[i].Min[2]); Vector3f xTerm = xExtent*Vector3f::UNIT_X; Vector3f yTerm = yExtent*Vector3f::UNIT_Y; Vector3f zTerm = zExtent*Vector3f::UNIT_Z; TriMesh* mesh = StaticCast<TriMesh>(mScene->GetChild(i)); VertexBufferAccessor vba(mesh); vba.Position<Vector3f>(0) = center - xTerm - yTerm - zTerm; vba.Position<Vector3f>(1) = center + xTerm - yTerm - zTerm; vba.Position<Vector3f>(2) = center + xTerm + yTerm - zTerm; vba.Position<Vector3f>(3) = center - xTerm + yTerm - zTerm; vba.Position<Vector3f>(4) = center - xTerm - yTerm + zTerm; vba.Position<Vector3f>(5) = center + xTerm - yTerm + zTerm; vba.Position<Vector3f>(6) = center + xTerm + yTerm + zTerm; vba.Position<Vector3f>(7) = center - xTerm + yTerm + zTerm; mesh->UpdateModelSpace(Visual::GU_NORMALS); mRenderer->Update(mesh->GetVertexBuffer()); }
//---------------------------------------------------------------------------- void Polysegments::CreateScene () { mScene = new0 Node(); 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(128, vstride); VertexBufferAccessor vba(vformat, vbuffer); for (int i = 0; i < vba.GetNumVertices(); ++i) { vba.Position<Float3>(i) = Float3(Mathf::SymmetricRandom(), Mathf::SymmetricRandom(), Mathf::SymmetricRandom()); vba.Color<Float3>(0, i) = Float3(Mathf::UnitRandom(), Mathf::UnitRandom(), Mathf::UnitRandom()); } mPolysegment = new0 Polysegment(vformat, vbuffer, true); mPolysegment->SetEffectInstance( VertexColor3Effect::CreateUniqueInstance()); mScene->AttachChild(mPolysegment); }
//---------------------------------------------------------------------------- Polysegment* BSplineFitContinuous::ReducedPolysegment (int numCtrlPoints, Vector3d* ctrlPoints, double fraction) { int numLSCtrlPoints; Vector3d* lsCtrlPoints; BSplineReduction3d(numCtrlPoints, ctrlPoints, mDegree, fraction, numLSCtrlPoints, lsCtrlPoints); BSplineCurve3d spline(numLSCtrlPoints, lsCtrlPoints, mDegree, false, true); delete1(lsCtrlPoints); 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(numCtrlPoints, vstride); VertexBufferAccessor vba(vformat, vbuffer); Float3 blue(0.0f, 0.0f, 1.0f); for (int i = 0; i < numCtrlPoints; ++i) { double t = i/(double)numCtrlPoints; Vector3d pos = spline.GetPosition(t); vba.Position<Float3>(i) = Float3((float)pos[0], (float)pos[1], (float)pos[2]); vba.Color<Float3>(0, i) = blue; } Polysegment* segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); return segment; }
//---------------------------------------------------------------------------- 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)); }
//---------------------------------------------------------------------------- Polypoint* FoucaultPendulum::CreatePath () { // Points used to display path of pendulum. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); const int numPoints = 8192; VertexBuffer* vbuffer = new0 VertexBuffer(numPoints, vstride); VertexBufferAccessor vba(vformat, vbuffer); Float3 zero(0.0f, 0.0f, 0.0f); Float3 white(1.0f, 1.0f, 1.0f); for (int i = 0; i < numPoints; ++i) { vba.Position<Float3>(i) = zero; vba.Color<Float3>(0, i) = white; } mPath = new0 Polypoint(vformat, vbuffer); mPath->SetNumPoints(1); mNextPoint = 0; mColorDiff = 1.0f/(float)numPoints; mPath->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); return mPath; }
//---------------------------------------------------------------------------- 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()); }
//---------------------------------------------------------------------------- void VolumeFog::CreateScene () { // Create a screen-space camera for the background image. mScreenCamera = ScreenTarget::CreateCamera(); // Create a screen polygon for the background image. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); mScreenPolygon = ScreenTarget::CreateRectangle(vformat, GetWidth(), GetHeight(), 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); std::string skyName = Environment::GetPathR("BlueSky.wmtf"); Texture2D* skyTexture = Texture2D::LoadWMTF(skyName); Texture2DEffect* skyEffect = new0 Texture2DEffect(); mScreenPolygon->SetEffectInstance(skyEffect->CreateInstance(skyTexture)); // Create the scene graph for the terrain. mScene = new0 Node(); // Begin with a flat height field. vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT4, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); mMesh = StandardMesh(vformat).Rectangle(64, 64, 8.0f, 8.0f); mScene->AttachChild(mMesh); // Set the heights based on a precomputed height field. Also create a // texture image to go with the height field. std::string heightFieldName = Environment::GetPathR("HeightField.wmtf"); Texture2D* heightTexture = Texture2D::LoadWMTF(heightFieldName); unsigned char* data = (unsigned char*)heightTexture->GetData(0); Float4 white(1.0f, 1.0f, 1.0f, 0.0f); VertexBufferAccessor vba(mMesh); for (int i = 0; i < vba.GetNumVertices(); ++i) { unsigned char value = *data; float height = 3.0f*value/255.0f + 0.05f*Mathf::SymmetricRandom(); *data++ = (unsigned char)Mathf::IntervalRandom(32.0f, 64.0f); *data++ = 3*(128 - value/2)/4; *data++ = 0; *data++ = 255; vba.Position<Float3>(i)[2] = height; // The fog color is white. The alpha channel is filled in by the // function UpdateFog(). vba.Color<Float4>(0, i) = white; } UpdateFog(); std::string effectFile = Environment::GetPathR("VolumeFog.wmfx"); VolumeFogEffect* effect = new0 VolumeFogEffect(effectFile); mMesh->SetEffectInstance(effect->CreateInstance(heightTexture)); }
//---------------------------------------------------------------------------- void BlendedAnimations::Update () { // Animate the biped. mManager.Update(mUpArrowPressed, mShiftPressed); mScene->Update(mAnimTime); mAnimTime += mAnimTimeDelta; // Give the impression the floor is moving by translating the texture // coordinates. For this demo, the texture coordinates are modified in // the vertex buffer. Generally, you could write a vertex shader with // time and velocity as inputs, and then compute the new texture // coordinates in the shader. #ifdef _DEBUG float adjust = mManager.GetSpeed()/16.0f; #else float adjust = mManager.GetSpeed()/160.0f; #endif VertexBufferAccessor vba(mFloor); for (int i = 0; i < vba.GetNumVertices(); ++i) { Float2& tcoord = vba.TCoord<Float2>(0, i); tcoord[1] -= adjust; } mRenderer->Update(mFloor->GetVertexBuffer()); }
//---------------------------------------------------------------------------- void BlendedAnimations::CreateScene () { mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mScene = new0 Node(); mScene->AttachChild(mManager.GetRoot()); // Create a floor to walk on. 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); mFloor = StandardMesh(vformat).Rectangle(2, 2, 1024.0f, 2048.0f); VertexBufferAccessor vba(mFloor); for (int i = 0; i < vba.GetNumVertices(); ++i) { Float2& tcoord = vba.TCoord<Float2>(0, i); tcoord[0] *= 64.0f; tcoord[1] *= 256.0f; } std::string textureName = Environment::GetPathR("Grating.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(textureName); texture->GenerateMipmaps(); mFloor->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture, Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT)); mScene->AttachChild(mFloor); ComputeVisibleSet(mScene); }
//---------------------------------------------------------------------------- void IntersectTriangleCylinder::TestIntersection () { Triangle3f triangle; triangle.V[0] = (const Vector3f&)(mTMesh->WorldTransform*mTriangleMVertex0); triangle.V[1] = (const Vector3f&)(mTMesh->WorldTransform*mTriangleMVertex1); triangle.V[2] = (const Vector3f&)(mTMesh->WorldTransform*mTriangleMVertex2); Cylinder3f cylinder; cylinder.Axis.Origin = (const Vector3f&)(mCMesh->WorldTransform*APoint::ORIGIN); cylinder.Axis.Direction = (const Vector3f&)(mCMesh->WorldTransform*AVector::UNIT_Z); cylinder.Radius = mCylinderRadius; cylinder.Height = mCylinderHeight; VertexBufferAccessor vba(mTMesh); if (IntrTriangle3Cylinder3f(triangle, cylinder).Test()) { vba.Color<Float3>(0, 0) = Float3(0.0f, 1.0f, 0.0f); vba.Color<Float3>(0, 1) = Float3(0.0f, 1.0f, 0.0f); vba.Color<Float3>(0, 2) = Float3(0.0f, 1.0f, 0.0f); } else { vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 1.0f); vba.Color<Float3>(0, 1) = Float3(0.0f, 0.0f, 1.0f); vba.Color<Float3>(0, 2) = Float3(0.0f, 0.0f, 1.0f); } mRenderer->Update(mTMesh->GetVertexBuffer()); }
//---------------------------------------------------------------------------- void Fluids3D::UpdateVertexBuffer () { VertexBufferAccessor vba(mCube); const int bound0 = mSmoke->GetIMax() + 1; const int bound1 = mSmoke->GetJMax() + 1; const int bound2 = mSmoke->GetKMax() + 1; float*** density = mSmoke->GetDensity(); for (int i2 = 0, index = 0; i2 < bound2; ++i2) { for (int i1 = 0; i1 < bound1; ++i1) { for (int i0 = 0; i0 < bound0; ++i0) { const float scaleDown = 0.5f; float value = density[i2][i1][i0]; if (value > 1.0f) { value = 1.0f; } Float4 color; if (mUseColor) { Vector3f key = mColor[(int)(255.0f*value)]; color[0] = key[0]; color[1] = key[1]; color[2] = key[2]; color[3] = scaleDown*value; } else { color[0] = scaleDown*value; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; } const float alphaThreshold = 0.01f; if (color[3] < alphaThreshold) { color[3] = 0.0f; } #ifdef USE_PARTICLES vba.Color<Float4>(0, index++) = color; vba.Color<Float4>(0, index++) = color; vba.Color<Float4>(0, index++) = color; vba.Color<Float4>(0, index++) = color; #else vba.Color<Float4>(0, index++) = color; #endif } } } mRenderer->Update(mCube->GetVertexBuffer()); }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- void PointInPolyhedron::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Create a semitransparent sphere mesh. VertexFormat* vformatMesh = VertexFormat::Create(1, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0); TriMesh* mesh = StandardMesh(vformatMesh).Sphere(16, 16, 1.0f); Material* material = new0 Material(); material->Diffuse = Float4(1.0f, 0.0f, 0.0f, 0.25f); VisualEffectInstance* instance = MaterialEffect::CreateUniqueInstance( material); instance->GetEffect()->GetAlphaState(0, 0)->BlendEnabled = true; mesh->SetEffectInstance(instance); // Create the data structures for the polyhedron that represents the // sphere mesh. CreateQuery(mesh); // Create a set of random points. Points inside the polyhedron are // colored white. Points outside the polyhedron are colored blue. 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(1024, vstride); VertexBufferAccessor vba(vformat, vbuffer); Float3 white(1.0f, 1.0f, 1.0f); Float3 blue(0.0f, 0.0f, 1.0f); for (int i = 0; i < vba.GetNumVertices(); ++i) { Vector3f random(Mathf::SymmetricRandom(), Mathf::SymmetricRandom(), Mathf::SymmetricRandom()); vba.Position<Vector3f>(i) = random; if (mQuery->Contains(random)) { vba.Color<Float3>(0, i) = white; } else { vba.Color<Float3>(0, i) = blue; } } DeleteQuery(); mPoints = new0 Polypoint(vformat, vbuffer); mPoints->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mScene->AttachChild(mPoints); mScene->AttachChild(mesh); }
//---------------------------------------------------------------------------- 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)); }
//---------------------------------------------------------------------------- void FreeFormDeformation::UpdateMesh () { VertexBufferAccessor vba(mMesh); int numVertices = vba.GetNumVertices(); for (int i = 0; i < numVertices; ++i) { const Vector3f& param = mParameters[i]; Vector3f& position = vba.Position<Vector3f>(i); position = mVolume->GetPosition(param[0], param[1], param[2]); } mRenderer->Update(mMesh->GetVertexBuffer()); }
//---------------------------------------------------------------------------- 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(); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- void Delaunay3D::ChangeTetraStatus (int index, const Float4& color, bool enableWire) { Visual* tetra = DynamicCast<Visual>(mScene->GetChild(1 + index)); assertion(tetra != 0, "Expecting a Visual object.\n"); VertexBufferAccessor vba(tetra); for (int i = 0; i < 4; ++i) { vba.Color<Float4>(0, i) = color; } mRenderer->Update(tetra->GetVertexBuffer()); VisualEffectInstance* instance = tetra->GetEffectInstance(); instance->GetEffect()->GetWireState(0, 0)->Enabled = enableWire; }
//---------------------------------------------------------------------------- void FoucaultPendulum::PhysicsTick () { mModule.Update(); // Update the pendulum mechanism. The pendulum rod is attached at // (x,y,z) = (0,0,16). The update here has the 16 hard-coded. mPendulum->LocalTransform.SetRotate(mModule.GetOrientation()); mPendulum->Update(); // Draw only the active quantity of pendulum points for the initial // portion of the simulation. Once all points are activated, then all // are drawn. mPath->SetNumPoints(mPath->GetNumPoints() + 1); // Add the new pendulum point to the point system. The initial color is // white. All previously known points have their colors decremented to // cause them to become dim over time. APoint proj = mPendulum->WorldTransform*APoint(0.0f, 0.0f, -16.0f); proj[2] = 0.0f; VertexBufferAccessor vba(mPath); vba.Position<Float3>(mNextPoint) = proj; vba.Color<Float3>(0, mNextPoint) = Float3(1.0f, 1.0f, 1.0f); int i; for (i = 0; i < mNextPoint; ++i) { Float3& color = vba.Color<Float3>(0, i); color[0] -= mColorDiff; color[1] -= mColorDiff; color[2] -= mColorDiff; } for (i = mNextPoint+1; i < vba.GetNumVertices(); ++i) { Float3& color = vba.Color<Float3>(0, i); color[0] -= mColorDiff; color[1] -= mColorDiff; color[2] -= mColorDiff; } // Prepare for the next pendulum point. if (++mNextPoint == vba.GetNumVertices()) { mNextPoint = 0; } mRenderer->Update(mPath->GetVertexBuffer()); }
//---------------------------------------------------------------------------- void CollisionsBoundTree::ResetColors () { VertexBufferAccessor vba(mCylinder0); int i; for (i = 0; i < vba.GetNumVertices(); ++i) { vba.TCoord<Float2>(0, i) = mBlueUV; } mRenderer->Update(mCylinder0->GetVertexBuffer()); vba.ApplyTo(mCylinder1); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.TCoord<Float2>(0, i) = mRedUV; } mRenderer->Update(mCylinder1->GetVertexBuffer()); }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- TriMesh* ConvexHull3D::CreateSphere () { VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); Float3 white(1.0f, 1.0f, 1.0f); float radius = 0.01f; TriMesh* sphere = StandardMesh(vformat).Sphere(8, 8, radius); VertexBufferAccessor vba(sphere); for (int i = 0; i < vba.GetNumVertices(); ++i) { vba.Color<Float3>(0, i) = white; } sphere->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); return sphere; }
//---------------------------------------------------------------------------- Polysegment* PolyhedronDistance::CreateSegment () { 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(2, vstride); VertexBufferAccessor vba(vformat, vbuffer); vba.Position<Vector3f>(0) = Vector3f::ZERO; vba.Position<Vector3f>(1) = Vector3f::UNIT_X; vba.Color<Float3>(0, 0) = Float3(1.0f, 1.0f, 1.0f); vba.Color<Float3>(0, 1) = Float3(1.0f, 1.0f, 1.0f); Polysegment* segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); return segment; }
//---------------------------------------------------------------------------- void RigidTetra::GetVertices (Vector3f* vertices) const { // Do not move the boundaries. The hard-coded numbers here depend on // those of the floor/walls in the application. Vector3f offset; if (0.0f < mPosition.X() && mPosition.X() < 20.0f) { offset = mPosition; } else { offset = Vector3f::ZERO; } // Move the tetra vertices. VertexBufferAccessor vba(mMesh); for (int i = 0; i < 4; ++i) { vertices[i] = mRotOrient*vba.Position<Vector3f>(i) + offset; } }
//---------------------------------------------------------------------------- BspNode* BspNodes::CreateNode (const Vector2f& v0, const Vector2f& v1, VertexColor3Effect* effect, const Float3& color) { // Create the model-space separating plane. Vector2f dir = v1 - v0; AVector normal(dir[1], -dir[0], 0.0f); normal.Normalize(); float constant = normal[0]*v0[0] + normal[1]*v0[1]; HPlane modelPlane(normal, constant); // Create the BSP node. BspNode* bsp = new0 BspNode(modelPlane); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); // Create the rectangle representation of the model plane and set the // vertex colors to the specified color. float xExtent = 0.5f*dir.Length(); float yExtent = 0.125f; TriMesh* rect = StandardMesh(vformat).Rectangle(2, 2, xExtent, yExtent); VertexBufferAccessor vba(rect); for (int i = 0; i < 4; ++i) { vba.Color<Float3>(0, i) = color; } rect->SetEffectInstance(effect->CreateInstance()); // Set the position and orientation for the world-space plane. APoint trn(0.5f*(v0[0] + v1[0]), 0.5f*(v0[1] + v1[1]), yExtent + 0.001f); HMatrix zRotate(AVector::UNIT_Z, Mathf::ATan2(dir.Y(),dir.X())); HMatrix xRotate(AVector::UNIT_X, Mathf::HALF_PI); HMatrix rotate = zRotate*xRotate; rect->LocalTransform.SetTranslate(trn); rect->LocalTransform.SetRotate(rotate); bsp->AttachCoplanarChild(rect); return bsp; }
//---------------------------------------------------------------------------- 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; }