//---------------------------------------------------------------------------- void ExtremalQuery::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); mCullState = new0 CullState(); mCullState->Enabled = false; mRenderer->SetOverrideCullState(mCullState); const int numVertices = 32; CreateConvexPolyhedron(numVertices); mScene->AttachChild(CreateVisualConvexPolyhedron()); // Use small spheres to show the extreme points in the camera's right // direction. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); StandardMesh sm(vformat); VertexColor3Effect* effect = new0 VertexColor3Effect(); // maximum sphere mMaxSphere = sm.Sphere(8, 8, 0.05f); mMaxSphere->SetEffectInstance(effect->CreateInstance()); mScene->AttachChild(mMaxSphere); // minimum sphere mMinSphere = sm.Sphere(8, 8, 0.05f); mMinSphere->SetEffectInstance(effect->CreateInstance()); mScene->AttachChild(mMinSphere); UpdateExtremePoints(); }
//---------------------------------------------------------------------------- void CollisionsMovingSpheres::CreateScene () { mScene = new0 Node(); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); StandardMesh sm(vformat); mSphere0.Radius = 0.1f; mSphere1.Radius = 0.2f; mVelocity0 = Vector3f(0.0f, -1.0f, 0.0f); mVelocity1 = Vector3f(0.0f, 0.0f, 1.0f); mMesh0 = sm.Sphere(16, 16, mSphere0.Radius); mMesh1 = sm.Sphere(16, 16, mSphere1.Radius); VertexBufferAccessor vba0(mMesh0), vba1(mMesh1); for (int i = 0; i < vba0.GetNumVertices(); ++i) { vba0.Color<Float3>(0, i) = Float3(Mathf::UnitRandom(), 0.0f, 0.0f); vba1.Color<Float3>(0, i) = Float3(0.0f, 0.0f, Mathf::UnitRandom()); } VertexColor3Effect* effect = new0 VertexColor3Effect(); mMesh0->SetEffectInstance(effect->CreateInstance()); mMesh1->SetEffectInstance(effect->CreateInstance()); mSphere0.Center = Vector3f(0.0f, 0.75f, 0.0f); mSphere1.Center = Vector3f(0.0f, -0.75f, 0.0f); mMesh0->LocalTransform.SetTranslate(mSphere0.Center); mMesh1->LocalTransform.SetTranslate(mSphere1.Center); mScene->AttachChild(mMesh0); mScene->AttachChild(mMesh1); }
//---------------------------------------------------------------------------- Node* RoughPlaneSolidBox::CreateBox () { mBox = new0 Node(); float xExtent = (float)mModule.XLocExt; float yExtent = (float)mModule.YLocExt; float zExtent = (float)mModule.ZLocExt; VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); StandardMesh sm(vformat); VertexColor3Effect* effect = new0 VertexColor3Effect(); VertexBufferAccessor vba; Transform transform; TriMesh* face; int i; // +z face Float3 red(1.0f, 0.0f, 0.0f); transform.SetTranslate(APoint(0.0f, 0.0f, zExtent)); sm.SetTransform(transform); face = sm.Rectangle(2, 2, xExtent, yExtent); vba.ApplyTo(face); for (i = 0; i < 4; ++i) { vba.Color<Float3>(0, 0) = red; vba.Color<Float3>(0, 1) = red; vba.Color<Float3>(0, 2) = red; vba.Color<Float3>(0, 3) = red; } face->SetEffectInstance(effect->CreateInstance()); mBox->AttachChild(face); // -z face Float3 darkRed(0.5f, 0.0f, 0.0f); transform.SetTranslate(APoint(0.0f, 0.0f, -zExtent)); transform.SetRotate(HMatrix(AVector::UNIT_Y, AVector::UNIT_X, -AVector::UNIT_Z, APoint::ORIGIN, true)); sm.SetTransform(transform); face = sm.Rectangle(2, 2, yExtent, xExtent); vba.ApplyTo(face); for (i = 0; i < 4; ++i) { vba.Color<Float3>(0, 0) = darkRed; vba.Color<Float3>(0, 1) = darkRed; vba.Color<Float3>(0, 2) = darkRed; vba.Color<Float3>(0, 3) = darkRed; } face->SetEffectInstance(effect->CreateInstance()); mBox->AttachChild(face); // +y face Float3 green(0.0f, 1.0f, 0.0f); transform.SetTranslate(APoint(0.0f, yExtent, 0.0f)); transform.SetRotate(HMatrix(AVector::UNIT_Z, AVector::UNIT_X, AVector::UNIT_Y, APoint::ORIGIN, true)); sm.SetTransform(transform); face = sm.Rectangle(2, 2, zExtent, xExtent); vba.ApplyTo(face); for (i = 0; i < 4; ++i) { vba.Color<Float3>(0, 0) = green; vba.Color<Float3>(0, 1) = green; vba.Color<Float3>(0, 2) = green; vba.Color<Float3>(0, 3) = green; } face->SetEffectInstance(effect->CreateInstance()); mBox->AttachChild(face); // -y face Float3 darkGreen(0.0f, 1.0f, 0.0f); transform.SetTranslate(APoint(0.0f, -yExtent, 0.0f)); transform.SetRotate(HMatrix(AVector::UNIT_X, AVector::UNIT_Z, -AVector::UNIT_Y, APoint::ORIGIN, true)); sm.SetTransform(transform); face = sm.Rectangle(2, 2, xExtent, zExtent); vba.ApplyTo(face); for (i = 0; i < 4; ++i) { vba.Color<Float3>(0, 0) = darkGreen; vba.Color<Float3>(0, 1) = darkGreen; vba.Color<Float3>(0, 2) = darkGreen; vba.Color<Float3>(0, 3) = darkGreen; } face->SetEffectInstance(effect->CreateInstance()); mBox->AttachChild(face); // +x face Float3 blue(0.0f, 0.0f, 1.0f); transform.SetTranslate(APoint(xExtent, 0.0f, 0.0f)); transform.SetRotate(HMatrix(AVector::UNIT_Y, AVector::UNIT_Z, AVector::UNIT_X, APoint::ORIGIN, true)); sm.SetTransform(transform); face = sm.Rectangle(2, 2, yExtent, zExtent); vba.ApplyTo(face); for (i = 0; i < 4; ++i) { vba.Color<Float3>(0, 0) = blue; vba.Color<Float3>(0, 1) = blue; vba.Color<Float3>(0, 2) = blue; vba.Color<Float3>(0, 3) = blue; } face->SetEffectInstance(effect->CreateInstance()); mBox->AttachChild(face); // -x face Float3 darkBlue(0.0f, 0.0f, 1.0f); transform.SetTranslate(APoint(-xExtent, 0.0f, 0.0f)); transform.SetRotate(HMatrix(AVector::UNIT_Z, AVector::UNIT_Y, -AVector::UNIT_X, APoint::ORIGIN, true)); sm.SetTransform(transform); face = sm.Rectangle(2, 2, zExtent, yExtent); vba.ApplyTo(face); for (i = 0; i < 4; ++i) { vba.Color<Float3>(0, 0) = darkBlue; vba.Color<Float3>(0, 1) = darkBlue; vba.Color<Float3>(0, 2) = darkBlue; vba.Color<Float3>(0, 3) = darkBlue; } face->SetEffectInstance(effect->CreateInstance()); mBox->AttachChild(face); MoveBox(); return mBox; }
//---------------------------------------------------------------------------- void PolygonOffsets::CreateScene () { mScene = new0 Node(); 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(); // Vertices to be shared by rectangles 1 and 3. VertexBuffer* vbuffer0 = new0 VertexBuffer(4, vstride); VertexBufferAccessor vba(vformat, vbuffer0); vba.Position<Float3>(0) = Float3(-1.0f, 0.0f, -1.0f); vba.Position<Float3>(1) = Float3(-1.0f, 0.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, 0.0f, +1.0f); vba.Position<Float3>(3) = Float3(+1.0f, 0.0f, -1.0f); vba.Color<Float3>(0, 0) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 1) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 2) = Float3(1.0f, 0.0f, 0.0f); vba.Color<Float3>(0, 3) = Float3(1.0f, 0.0f, 0.0f); // Vertices to be shared by rectangles 2 and 4. VertexBuffer* vbuffer1 = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer1); vba.Position<Float3>(0) = Float3(-1.0f, 0.0f, -1.0f); vba.Position<Float3>(1) = Float3(-1.0f, 0.0f, +1.0f); vba.Position<Float3>(2) = Float3(+1.0f, 0.0f, +1.0f); vba.Position<Float3>(3) = Float3(+1.0f, 0.0f, -1.0f); 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); vba.Color<Float3>(0, 3) = Float3(0.0f, 1.0f, 0.0f); // Indices to be shared by all rectangles. 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; // Effect to be shared by the first three rectangles. VertexColor3Effect* effect = new0 VertexColor3Effect(); // rectangle 1 TriMesh* mesh = new0 TriMesh(vformat, vbuffer0, ibuffer); mesh->SetEffectInstance(effect->CreateInstance()); mesh->LocalTransform.SetTranslate(APoint(+2.0f, -4.0f, 0.0f)); mScene->AttachChild(mesh); // rectangle 2 mesh = new0 TriMesh(vformat, vbuffer1, ibuffer); mesh->SetEffectInstance(effect->CreateInstance()); mesh->LocalTransform.SetTranslate(APoint(+2.0f, -4.0f, 0.0f)); mesh->LocalTransform.SetUniformScale(0.5f); mScene->AttachChild(mesh); // rectangle 3 mesh = new0 TriMesh(vformat, vbuffer0, ibuffer); mesh->SetEffectInstance(effect->CreateInstance()); mesh->LocalTransform.SetTranslate(APoint(-2.0f, -4.0f, 0.0f)); mScene->AttachChild(mesh); // rectangle 4 mesh = new0 TriMesh(vformat, vbuffer1, ibuffer); mesh->LocalTransform.SetTranslate(APoint(-2.0f, -4.0f, 0.0f)); mesh->LocalTransform.SetUniformScale(0.5f); mScene->AttachChild(mesh); // Set up the polygon offset for rectangle 4. effect = new0 VertexColor3Effect(); OffsetState* ostate = effect->GetOffsetState(0, 0); ostate->FillEnabled = true; ostate->Scale = -1.0f; ostate->Bias = -2.0f; mesh->SetEffectInstance(effect->CreateInstance()); }
//---------------------------------------------------------------------------- void BspNodes::CreateScene () { // Create the scene graph. // // 1. The rectangles represent the BSP planes of the BSP tree. They // share a VertexColor3Effect. You can see a plane from either side // (backface culling disabled). The planes do not interfere with view // of the solid objects (wirestate enabled). // // 2. The sphere, tetrahedron, and cube share a TextureEffect. These // objects are convex. The backfacing triangles are discarded // (backface culling enabled). The front facing triangles are drawn // correctly by convexity, so depthbuffer reads are disabled and // depthbuffer writes are enabled. The BSP-based sorting of objects // guarantees that front faces of convex objects in the foreground // are drawn after the front faces of convex objects in the background, // which allows us to set the depthbuffer state as we have. That is, // BSPNode sorts from back to front. // // 3. The torus has backface culling enabled and depth buffering enabled. // This is necessary, because the torus is not convex. // // 4. Generally, if all objects are opaque, then you want to draw from // front to back with depth buffering fully enabled. You need to // reverse-order the elements of the visible set before drawing. If // any of the objects are semitransparent, then drawing back to front // is the correct order to handle transparency. However, you do not // get the benefit of early z-rejection for opaque objects. A better // BSP sorter needs to be built to produce a visible set with opaque // objects listed first (front-to-back order) and semitransparent // objects listed last (back-to-front order). // // scene // ground // bsp0 // bsp1 // bsp3 // torus // rectangle3 // sphere // rectangle1 // tetrahedron // rectangle0 // bsp2 // cube // rectangle2 // octahedron mScene = new0 Node(); // Create the ground. It covers a square with vertices (1,1,0), (1,-1,0), // (-1,1,0), and (-1,-1,0). Multiply the texture coordinates by a factor // to enhance the wrap-around. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); StandardMesh sm(vformat); VertexBufferAccessor vba; TriMesh* ground = sm.Rectangle(2, 2, 16.0f, 16.0f); vba.ApplyTo(ground); for (int i = 0; i < vba.GetNumVertices(); ++i) { Float2& tcoord = vba.TCoord<Float2>(0, i); tcoord[0] *= 128.0f; tcoord[1] *= 128.0f; } std::string path = Environment::GetPathR("Horizontal.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); ground->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture, Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT)); mScene->AttachChild(ground); // Partition the region above the ground into 5 convex pieces. Each plane // is perpendicular to the ground (not required generally). VertexColor3Effect* vceffect = new0 VertexColor3Effect(); vceffect->GetCullState(0, 0)->Enabled = false; vceffect->GetWireState(0, 0)->Enabled = true; Vector2f v0(-1.0f, 1.0f); Vector2f v1(1.0f, -1.0f); Vector2f v2(-0.25f, 0.25f); Vector2f v3(-1.0f, -1.0f); Vector2f v4(0.0f, 0.0f); Vector2f v5(1.0f, 0.5f); Vector2f v6(-0.75f, -7.0f/12.0f); Vector2f v7(-0.75f, 0.75f); Vector2f v8(1.0f, 1.0f); BspNode* bsp0 = CreateNode(v0, v1, vceffect, Float3(1.0f, 0.0f, 0.0f)); BspNode* bsp1 = CreateNode(v2, v3, vceffect, Float3(0.0f, 0.5f, 0.0f)); BspNode* bsp2 = CreateNode(v4, v5, vceffect, Float3(0.0f, 0.0f, 1.0f)); BspNode* bsp3 = CreateNode(v6, v7, vceffect, Float3(0.0f, 0.0f, 0.0f)); bsp0->AttachPositiveChild(bsp1); bsp0->AttachNegativeChild(bsp2); bsp1->AttachPositiveChild(bsp3); // Attach an object in each convex region. float height = 0.1f; Vector2f center; TriMesh* mesh; // The texture effect for the convex objects. Texture2DEffect* cvxeffect = new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR); cvxeffect->GetDepthState(0, 0)->Enabled = false; cvxeffect->GetDepthState(0, 0)->Writable = true; // The texture effect for the torus. Texture2DEffect* toreffect = new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR); // The texture image shared by the objects. path = Environment::GetPathR("Flower.wmtf"); texture = Texture2D::LoadWMTF(path); // Region 0: Create a torus mesh. mesh = sm.Torus(16, 16, 1.0f, 0.25f); mesh->SetEffectInstance(toreffect->CreateInstance(texture)); mesh->LocalTransform.SetUniformScale(0.1f); center = (v2 + v6 + v7)/3.0f; mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height)); bsp3->AttachPositiveChild(mesh); // Region 1: Create a sphere mesh. mesh = sm.Sphere(32, 16, 1.0f); mesh->SetEffectInstance(cvxeffect->CreateInstance(texture)); mesh->LocalTransform.SetUniformScale(0.1f); center = (v0 + v3 + v6 + v7)/4.0f; mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height)); bsp3->AttachNegativeChild(mesh); // Region 2: Create a tetrahedron. mesh = sm.Tetrahedron(); mesh->SetEffectInstance(cvxeffect->CreateInstance(texture)); mesh->LocalTransform.SetUniformScale(0.1f); center = (v1 + v2 + v3)/3.0f; mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height)); bsp1->AttachNegativeChild(mesh); // Region 3: Create a hexahedron (cube). mesh = sm.Hexahedron(); mesh->SetEffectInstance(cvxeffect->CreateInstance(texture)); mesh->LocalTransform.SetUniformScale(0.1f); center = (v1 + v4 + v5)/3.0f; mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height)); bsp2->AttachPositiveChild(mesh); // Region 4: Create an octahedron. mesh = sm.Octahedron(); mesh->SetEffectInstance(cvxeffect->CreateInstance(texture)); mesh->LocalTransform.SetUniformScale(0.1f); center = (v0 + v4 + v5 + v8)/4.0f; mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height)); bsp2->AttachNegativeChild(mesh); mScene->AttachChild(bsp0); }
//---------------------------------------------------------------------------- void FreeFormDeformation::CreatePolylines () { // Generate the polylines that connect adjacent control points. mPolysegmentRoot = new0 Node(); mTrnNode->AttachChild(mPolysegmentRoot); VertexColor3Effect* effect = new0 VertexColor3Effect(); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); int vstride = vformat->GetStride(); VertexBufferAccessor vba; VertexBuffer* vbuffer; Polysegment* segment; int i0, i1, i2; for (i0 = 0; i0 < mQuantity; ++i0) { for (i1 = 0; i1 < mQuantity; ++i1) { for (i2 = 0; i2 < mQuantity-1; ++i2) { vbuffer = new0 VertexBuffer(2, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Vector3f>(0) = mVolume->GetControlPoint(i0, i1, i2); vba.Position<Vector3f>(1) = mVolume->GetControlPoint(i0, i1, i2+1); vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 0.75f); vba.Color<Float3>(0, 1) = Float3(0.0f, 0.0f, 0.75f); segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(effect->CreateInstance()); mPolysegmentRoot->AttachChild(segment); } } for (i2 = 0; i2 < mQuantity; ++i2) { for (i1 = 0; i1 < mQuantity-1; ++i1) { vbuffer = new0 VertexBuffer(2, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Vector3f>(0) = mVolume->GetControlPoint(i0, i1, i2); vba.Position<Vector3f>(1) = mVolume->GetControlPoint(i0, i1+1, i2); vba.Color<Float3>(0, 0) = Float3(0.0f, 0.75f, 0.0f); vba.Color<Float3>(0, 1) = Float3(0.0f, 0.75f, 0.0f); segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(effect->CreateInstance()); mPolysegmentRoot->AttachChild(segment); } } } for (i0 = 0; i0 < mQuantity-1; ++i0) { for (i1 = 0; i1 < mQuantity; ++i1) { for (i2 = 0; i2 < mQuantity; ++i2) { vbuffer = new0 VertexBuffer(2, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Vector3f>(0) = mVolume->GetControlPoint(i0, i1, i2); vba.Position<Vector3f>(1) = mVolume->GetControlPoint(i0+1, i1, i2); vba.Color<Float3>(0,0) = Float3(0.75f, 0.0f, 0.0f); vba.Color<Float3>(0,1) = Float3(0.75f, 0.0f, 0.0f); segment = new0 Polysegment(vformat, vbuffer, true); segment->SetEffectInstance(effect->CreateInstance()); mPolysegmentRoot->AttachChild(segment); } } } }