//---------------------------------------------------------------------------- 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 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); }
//---------------------------------------------------------------------------- void Billboard::GenBuffers () { Effectable::GenBuffers(); BillboardController *billCtrl = DynamicCast<BillboardController>( mEffectableCtrl); const EffectObject *billboardObject = billCtrl->GetBillboardObject(); if (!billboardObject) return; float age = billboardObject->Age; float uBegin = billboardObject->UV0Begin[0]; float uEnd = billboardObject->UV0End[0]; float vBegin = billboardObject->UV0Begin[1]; float vEnd = billboardObject->UV0End[1]; int uvIndex = GetUV(billboardObject->StartRandomIndex, age, uBegin, uEnd, vBegin, vEnd); float xPlusPer = 0.0f; float zPlusPer = 0.0f; float widthPer = 1.0f; float heightPer = 1.0f; if (IsUseTrim() && Effectable::TM_TEXPACK_ANIM==GetTexMode() && mTexPackAnim_Frames.size()>0) { if (0 != mTexPackAnim_Frames[uvIndex].OW) { xPlusPer = (float)mTexPackAnim_Frames[uvIndex].OX / (float)mTexPackAnim_Frames[uvIndex].OW; widthPer = (float)mTexPackAnim_Frames[uvIndex].W /(float)mTexPackAnim_Frames[uvIndex].OW; } if (0 != mTexPackAnim_Frames[uvIndex].OH) { zPlusPer = 1.0f - (float)(mTexPackAnim_Frames[uvIndex].OY+mTexPackAnim_Frames[uvIndex].H) / (float)mTexPackAnim_Frames[uvIndex].OH; heightPer = (float)mTexPackAnim_Frames[uvIndex].H /(float)mTexPackAnim_Frames[uvIndex].OH; } } float width = billboardObject->SizeX; float height = billboardObject->SizeY; float xPos = 0.0f - width * mPivotPoint[0]; float zPos = 0.0f - height * mPivotPoint[1]; xPos += xPlusPer * width; zPos += zPlusPer * height; width *= widthPer; height *= heightPer; Float3 color = billboardObject->Color; float alpha = billboardObject->Alpha; Float3 p0; Float3 p1; Float3 p2; Float3 p3; FaceType faceType = GetFaceType(); if (FT_X == faceType) { p0 = Float3(0.0f, xPos, zPos); p1 = Float3(0.0f, xPos+width, zPos); p2 = Float3(0.0f, xPos, zPos+height); p3 = Float3(0.0f, xPos+width, zPos+height); } else if (FT_NX == faceType) { p0 = Float3(0.0f, -xPos, zPos); p1 = Float3(0.0f, -(xPos+width), zPos); p2 = Float3(0.0f, -xPos, zPos+height); p3 = Float3(0.0f, -(xPos+width), zPos+height); } else if (FT_Y == faceType) { p0 = Float3(-xPos, 0.0f, zPos); p1 = Float3(-(xPos+width), 0.0f, zPos); p2 = Float3(-xPos, 0.0f, zPos+height); p3 = Float3(-(xPos+width), 0.0f, zPos+height); } else if (FT_NY == faceType) { p0 = Float3(xPos, 0.0f, zPos); p1 = Float3(xPos+width, 0.0f, zPos); p2 = Float3(xPos, 0.0f, zPos+height); p3 = Float3(xPos+width, 0.0f, zPos+height); } else if (FT_Z == faceType) { p0 = Float3(xPos, zPos, 0.0f); p1 = Float3(xPos+width, zPos, 0.0f); p2 = Float3(xPos, zPos+height, 0.0f); p3 = Float3(xPos+width, zPos+height, 0.0f); } else if (FT_NZ == faceType) { p0 = Float3(-xPos, zPos, 0.0f); p1 = Float3(-(xPos+width), zPos, 0.0f); p2 = Float3(-xPos, zPos+height, 0.0f); p3 = Float3(-(xPos+width), zPos+height, 0.0f); } else if (FT_CAMERA == faceType) { Camera *camera = PX2_GR.GetCurUpdateCamera(); if (!camera) return; const AVector &camUp = camera->GetUVector(); const AVector &camRight = camera->GetRVector(); float anchorWidth = mPivotPoint[0]*width; float anchorHeight = mPivotPoint[1]*height; APoint position; p0 = position - camRight * anchorWidth - camUp * anchorHeight; p1 = position + camRight * (width-anchorWidth) - camUp * anchorHeight; p2 = position - camRight * anchorWidth + camUp * (height-anchorHeight); p3 = position + camRight * (width-anchorWidth) + camUp * (height-anchorHeight); } else if (FT_SPEEDDIR==faceType || FT_FREE==faceType) { p0 = Float3(xPos, 0.0f, zPos); p1 = Float3(xPos+width, 0.0f, zPos); p2 = Float3(xPos, 0.0f, zPos+height); p3 = Float3(xPos+width, 0.0f, zPos+height); } //SetUseShareBuffers(true); if (!IsUseShareBuffers()) { VertexBufferAccessor vba(this); vba.Position<Float3>(0) = p0; vba.Position<Float3>(1) = p1; vba.Position<Float3>(2) = p2; vba.Position<Float3>(3) = p3; vba.Color<Float4>(0, 0) = Float4(color[0], color[1], color[2], alpha); vba.Color<Float4>(0, 1) = Float4(color[0], color[1], color[2], alpha); vba.Color<Float4>(0, 2) = Float4(color[0], color[1], color[2], alpha); vba.Color<Float4>(0, 3) = Float4(color[0], color[1], color[2], alpha); vba.TCoord<Float2>(0, 0) = Float2(uBegin, vBegin); vba.TCoord<Float2>(0, 1) = Float2(uEnd, vBegin); vba.TCoord<Float2>(0, 2) = Float2(uBegin, vEnd); vba.TCoord<Float2>(0, 3) = Float2(uEnd, vEnd); if (!IsFixedBound()) UpdateModelSpace(GU_MODEL_BOUND_ONLY); Renderer::UpdateAll(GetVertexBuffer()); } else { mDBObject_V = PX2_DBM.AllocVertexBuffer(4); mDBObject_I = PX2_DBM.AllocIndexBuffer(6); SetShareDBObject_V(mDBObject_V); SetShareDBObject_I(mDBObject_I); VertexBufferAccessor vba; vba.ApplyTo(GetVertexFormat(), mDBObject_V->Buf); vba.Position<Float3>(mDBObject_V->Offset+0) = p0; vba.Position<Float3>(mDBObject_V->Offset+1) = p1; vba.Position<Float3>(mDBObject_V->Offset+2) = p2; vba.Position<Float3>(mDBObject_V->Offset+3) = p3; vba.Color<Float4>(0, mDBObject_V->Offset+0) = Float4(color[0], color[1], color[2], alpha); vba.Color<Float4>(0, mDBObject_V->Offset+1) = Float4(color[0], color[1], color[2], alpha); vba.Color<Float4>(0, mDBObject_V->Offset+2) = Float4(color[0], color[1], color[2], alpha); vba.Color<Float4>(0, mDBObject_V->Offset+3) = Float4(color[0], color[1], color[2], alpha); vba.TCoord<Float2>(0, mDBObject_V->Offset+0) = Float2(uBegin, vBegin); vba.TCoord<Float2>(0, mDBObject_V->Offset+1) = Float2(uEnd, vBegin); vba.TCoord<Float2>(0, mDBObject_V->Offset+2) = Float2(uBegin, vEnd); vba.TCoord<Float2>(0, mDBObject_V->Offset+3) = Float2(uEnd, vEnd); unsigned short *indices = (unsigned short*)mDBObject_I->Buf->GetData(); indices += mDBObject_I->Offset; unsigned short v0 = (unsigned short)(mDBObject_V->Offset+0); unsigned short v1 = (unsigned short)(mDBObject_V->Offset+1); unsigned short v2 = (unsigned short)(mDBObject_V->Offset+2); unsigned short v3 = (unsigned short)(mDBObject_V->Offset+3); *indices++ = v0; *indices++ = v1; *indices++ = v2; *indices++ = v1; *indices++ = v3; *indices++ = v2; } }
//---------------------------------------------------------------------------- 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 IntersectInfiniteCylinders::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(); StandardMesh sm(vformat); VertexBufferAccessor vba; int i; // Create the canonical cylinder. mCylinder0 = sm.Cylinder(32, 128, mRadius0, mHeight, true); mScene->AttachChild(mCylinder0); mVisible.Insert(mCylinder0); vba.ApplyTo(mCylinder0); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.Color<Float3>(0, i) = Float3(0.5f, 0.0f, 0.0f); } mCylinder0->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); // Create the other cylinder. mCylinder1 = sm.Cylinder(32, 128, mRadius1, mHeight, true); mScene->AttachChild(mCylinder1); mVisible.Insert(mCylinder1); vba.ApplyTo(mCylinder1); for (i = 0; i < vba.GetNumVertices(); ++i) { vba.Color<Float3>(0, i) = Float3(0.0f, 0.0f, 0.5f); } mCylinder1->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mCylinder1->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, -mAngle)); mCylinder1->LocalTransform.SetTranslate(APoint(mC0, 0.0f, 0.0f)); // Create the intersection curve. const float minTheta = 2.0f*Mathf::PI/3.0f; const float maxTheta = 4.0f*Mathf::PI/3.0f; float theta, cs, sn, t, tmp, discr; VertexBuffer* vbuffer = new0 VertexBuffer(1024, vstride); mCurve0 = new0 Polysegment(vformat, vbuffer, true); mScene->AttachChild(mCurve0); vba.ApplyTo(mCurve0); int numPoints = vba.GetNumVertices(); float multiplier = (maxTheta - minTheta)/(float)(numPoints - 1); for (i = 0; i < numPoints; ++i) { theta = minTheta + multiplier*i; cs = Mathf::Cos(theta); sn = Mathf::Sin(theta); tmp = mC0 + mRadius1*cs; discr = Mathf::FAbs(mRadius0*mRadius0 - tmp*tmp); t = (-mRadius1*mW2*sn - Mathf::Sqrt(discr))/mW1; Float3& position = vba.Position<Float3>(i); position[0] = mC0 + mRadius1*cs; position[1] = +mRadius1*sn*mW2 + t*mW1; position[2] = -mRadius1*sn*mW1 + t*mW2; vba.Color<Float3>(0, i) = Float3(0.0f, 0.5f, 0.0f); } mCurve0->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mVisible.Insert(mCurve0); vbuffer = new0 VertexBuffer(1024, vstride); mCurve1 = new0 Polysegment(vformat, vbuffer, true); mScene->AttachChild(mCurve1); vba.ApplyTo(mCurve1); numPoints = vba.GetNumVertices(); multiplier = (maxTheta - minTheta)/(float)(numPoints - 1); for (i = 0; i < numPoints; ++i) { theta = minTheta + multiplier*i; cs = Mathf::Cos(theta); sn = Mathf::Sin(theta); tmp = mC0 + mRadius1*cs; discr = Mathf::FAbs(mRadius0*mRadius0 - tmp*tmp); t = (-mRadius1*mW2*sn + Mathf::Sqrt(discr))/mW1; Float3& position = vba.Position<Float3>(i); position[0] = mC0 + mRadius1*cs; position[1] = +mRadius1*sn*mW2 + t*mW1; position[2] = -mRadius1*sn*mW1 + t*mW2; vba.Color<Float3>(0, i) = Float3(0.0f, 0.5f, 0.0f); } mCurve1->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance()); mVisible.Insert(mCurve1); }
//---------------------------------------------------------------------------- PX2::Node *GeoObjFactory::CreateScaleCtrl_O() { // node PX2::Node *node = new0 Node; node->LocalTransform.SetUniformScale(2.0f); node->SetName("Scale"); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); StandardMesh stdMesh(vf); VertexBuffer *vBufferTemp = 0; VertexBufferAccessor vbaTemp; // x PX2::Node *nodeX = new0 Node; nodeX->SetName("Scale_X"); VertexBuffer *vBufferX = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaX(vf, vBufferX); vbaX.Position<Float3>(0) = Float3(0.25f, 0.0f, 0.0f); vbaX.Position<Float3>(1) = Float3(1.125f, 0.0f, 0.0f); vbaX.Color<Float4>(0, 0) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaX.Color<Float4>(0, 1) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaX.Position<Float3>(2) = Float3(0.5f, 0.0f, 0.0f); vbaX.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f); vbaX.Color<Float4>(0, 2) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaX.Color<Float4>(0, 3) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaX.Position<Float3>(4) = Float3(0.5f, 0.0f, 0.0f); vbaX.Position<Float3>(5) = Float3(0.5f, 0.0f, 0.5f); vbaX.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaX.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f); Polysegment *polysegmentX = new0 PX2::Polysegment(vf, vBufferX, false); polysegmentX->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeX->AttachChild(polysegmentX); TriMesh *meshX = stdMesh.Box(0.06f, 0.06f, 0.06f); meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f)); vBufferTemp = meshX->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f); } nodeX->AttachChild(meshX); // y PX2::Node *nodeY = new0 PX2::Node; nodeX->SetName("Scale_Y"); VertexBuffer *vBufferY = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaY(vf, vBufferY); vbaY.Position<Float3>(0) = Float3(0.0f, 0.25f, 0.0f); vbaY.Position<Float3>(1) = Float3(0.0f, 1.125f, 0.0f); vbaY.Color<Float4>(0, 0) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaY.Color<Float4>(0, 1) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaY.Position<Float3>(2) = Float3(0.0f, 0.5f, 0.0f); vbaY.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f); vbaY.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaY.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaY.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f); vbaY.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f); vbaY.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaY.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f); Polysegment *polysegmentY = new0 PX2::Polysegment(vf, vBufferY, false); polysegmentY->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeY->AttachChild(polysegmentY); TriMesh *meshY = stdMesh.Box(0.06f, 0.06f, 0.06f); meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f)); vBufferTemp = meshY->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f); } nodeY->AttachChild(meshY); // z PX2::Node *nodeZ = new0 PX2::Node(); nodeX->SetName("Scale_Z"); VertexBuffer *vBufferZ = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaZ(vf, vBufferZ); vbaZ.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.25f); vbaZ.Position<Float3>(1) = Float3(0.0f, 0.0f, 1.125f); vbaZ.Color<Float4>(0, 0) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaZ.Color<Float4>(0, 1) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaZ.Position<Float3>(2) = Float3(0.0f, 0.0f, 0.5f); vbaZ.Position<Float3>(3) = Float3(0.5f, 0.0f, 0.5f); vbaZ.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaZ.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaZ.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.5f); vbaZ.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f); vbaZ.Color<Float4>(0, 4) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaZ.Color<Float4>(0, 5) = Float4(0.0f, 1.0f, 0.0f, 1.0f); Polysegment *polysegmentZ = new0 PX2::Polysegment(vf, vBufferZ, false); polysegmentZ->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeZ->AttachChild(polysegmentZ); TriMesh *meshZ = stdMesh.Box(0.06f, 0.06f, 0.06f); meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshZ->LocalTransform.SetTranslate(APoint(.0f, 0.0f, 1.125f)); vBufferTemp = meshZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f); } nodeZ->AttachChild(meshZ); // XYZ node->AttachChild(nodeX); node->AttachChild(nodeY); node->AttachChild(nodeZ); return node; }
//---------------------------------------------------------------------------- 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); } } } }
//---------------------------------------------------------------------------- PX2::Node *GeoObjFactory::CreateRolateCtrl_O() { // node PX2::Node *node = new0 Node; node->LocalTransform.SetUniformScale(2.0f); node->SetName("Rolate"); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); StandardMesh stdMesh(vf); VertexBuffer *vBufferTemp = 0; VertexBufferAccessor vbaTemp; // x PX2::Node *nodeX = new0 Node; nodeX->SetName("Rolate_X"); TriMesh *meshX = stdMesh.Torus(40, 10, 1.0f, 0.04f);; meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y, -Mathf::HALF_PI)); vBufferTemp = meshX->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f); } nodeX->AttachChild(meshX); // y PX2::Node *nodeY = new0 PX2::Node; nodeX->SetName("Rolate_Y"); TriMesh *meshY = stdMesh.Torus(40, 10, 1.0f, 0.04f);; meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X, Mathf::HALF_PI)); vBufferTemp = meshY->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f); } nodeY->AttachChild(meshY); // z PX2::Node *nodeZ = new0 PX2::Node(); nodeX->SetName("Rolate_Z"); TriMesh *meshZ = stdMesh.Torus(40, 10, 1.0f, 0.04f);; meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshZ->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X, Mathf::PI)); vBufferTemp = meshZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f); } nodeZ->AttachChild(meshZ); // XYZ node->AttachChild(nodeX); node->AttachChild(nodeY); node->AttachChild(nodeZ); return node; }
//---------------------------------------------------------------------------- PX2::Node *GeoObjFactory::CreateTranslateCtrl_O() { // node PX2::Node *node = new0 Node; node->LocalTransform.SetUniformScale(2.0f); node->SetName("Translate"); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); StandardMesh stdMesh(vf); VertexBuffer *vBufferTemp = 0; VertexBufferAccessor vbaTemp; // x PX2::Node *nodeX = new0 Node; nodeX->SetName("Translate_X"); VertexBuffer *vBufferX = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaX(vf, vBufferX); vbaX.Position<Float3>(0) = Float3(0.25f, 0.0f, 0.0f); vbaX.Position<Float3>(1) = Float3(1.125f, 0.0f, 0.0f); vbaX.Color<Float4>(0, 0) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaX.Color<Float4>(0, 1) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaX.Position<Float3>(2) = Float3(0.5f, 0.0f, 0.0f); vbaX.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f); vbaX.Color<Float4>(0, 2) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaX.Color<Float4>(0, 3) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaX.Position<Float3>(4) = Float3(0.5f, 0.0f, 0.0f); vbaX.Position<Float3>(5) = Float3(0.5f, 0.0f, 0.5f); vbaX.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaX.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f); Polysegment *polysegmentX = new0 PX2::Polysegment(vf, vBufferX, false); polysegmentX->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeX->AttachChild(polysegmentX); TriMesh *meshX = stdMesh.Disk(3, 20, 0.1f); meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y, -Mathf::HALF_PI)); meshX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f)); vBufferTemp = meshX->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f); } nodeX->AttachChild(meshX); TriFan *fanX = stdMesh.Cone(20, 0.1f, 0.45f); fanX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //fanX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; fanX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y, Mathf::HALF_PI)); fanX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f)); vBufferTemp = fanX->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f); } nodeX->AttachChild(fanX); // y PX2::Node *nodeY = new0 PX2::Node; nodeX->SetName("Translate_Y"); VertexBuffer *vBufferY = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaY(vf, vBufferY); vbaY.Position<Float3>(0) = Float3(0.0f, 0.25f, 0.0f); vbaY.Position<Float3>(1) = Float3(0.0f, 1.125f, 0.0f); vbaY.Color<Float4>(0, 0) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaY.Color<Float4>(0, 1) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaY.Position<Float3>(2) = Float3(0.0f, 0.5f, 0.0f); vbaY.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f); vbaY.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaY.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaY.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f); vbaY.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f); vbaY.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaY.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f); Polysegment *polysegmentY = new0 PX2::Polysegment(vf, vBufferY, false); polysegmentY->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeY->AttachChild(polysegmentY); TriMesh *meshY = stdMesh.Disk(3, 20, 0.1f); meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X, Mathf::HALF_PI)); meshY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f)); vBufferTemp = meshY->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f); } nodeY->AttachChild(meshY); TriFan *fanY = stdMesh.Cone(20, 0.1f, 0.45f); fanY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //fanY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; fanY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X, -Mathf::HALF_PI)); fanY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f)); vBufferTemp = fanY->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f); } nodeY->AttachChild(fanY); // z PX2::Node *nodeZ = new0 PX2::Node(); nodeX->SetName("Translate_Z"); VertexBuffer *vBufferZ = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaZ(vf, vBufferZ); vbaZ.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.25f); vbaZ.Position<Float3>(1) = Float3(0.0f, 0.0f, 1.125f); vbaZ.Color<Float4>(0, 0) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaZ.Color<Float4>(0, 1) = Float4(0.0f, 0.0f, 1.0f, 1.0f); vbaZ.Position<Float3>(2) = Float3(0.0f, 0.0f, 0.5f); vbaZ.Position<Float3>(3) = Float3(0.5f, 0.0f, 0.5f); vbaZ.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaZ.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f); vbaZ.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.5f); vbaZ.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f); vbaZ.Color<Float4>(0, 4) = Float4(0.0f, 1.0f, 0.0f, 1.0f); vbaZ.Color<Float4>(0, 5) = Float4(0.0f, 1.0f, 0.0f, 1.0f); Polysegment *polysegmentZ = new0 PX2::Polysegment(vf, vBufferZ, false); polysegmentZ->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeZ->AttachChild(polysegmentZ); TriMesh *meshZ = stdMesh.Disk(3, 20, 0.1f); meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //meshZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; meshZ->LocalTransform.SetTranslate(APoint(.0f, 0.0f, 1.125f)); meshZ->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X, Mathf::PI)); vBufferTemp = meshZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f); } nodeZ->AttachChild(meshZ); TriFan *fanZ = stdMesh.Cone(20, 0.1f, 0.45f); fanZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); //fanZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true; fanZ->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, 1.125f)); vBufferTemp = fanZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f); } nodeZ->AttachChild(fanZ); // xy PX2::Node *nodeXY = new0 Node; nodeXY->SetName("Translate_XY"); TriMesh *meshXY = stdMesh.Rectangle(2, 2, 0.25f, 0.25f); meshXY->LocalTransform.SetTranslate(APoint(0.25f, 0.25f, 0.0f)); VertexColor4Material *matXY = new0 VertexColor4Material(); matXY->GetAlphaProperty(0, 0)->BlendEnabled = true; matXY->GetCullProperty(0, 0)->Enabled = false; meshXY->SetMaterialInstance(matXY->CreateInstance()); vBufferTemp = meshXY->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 1.0f, 0.0f, 0.0f); } nodeXY->AttachChild(meshXY); // yz PX2::Node *nodeYZ = new0 Node; nodeYZ->SetName("Translate_YZ"); TriMesh *meshYZ = stdMesh.Rectangle(2, 2, 0.25f, 0.25f); meshYZ->LocalTransform.SetTranslate(APoint(0.25f, 0.25f, 0.0f)); meshYZ->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(0.0f, -Mathf::HALF_PI, 0.0f)); VertexColor4Material *matYZ = new0 VertexColor4Material(); matYZ->GetAlphaProperty(0, 0)->BlendEnabled = true; matYZ->GetCullProperty(0, 0)->Enabled = false; meshYZ->SetMaterialInstance(matYZ->CreateInstance()); vBufferTemp = meshYZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 1.0f, 0.0f, 0.0f); } nodeYZ->AttachChild(meshYZ); // xz PX2::Node *nodeXZ = new0 Node; nodeXZ->SetName("Translate_XZ"); TriMesh *meshXZ = stdMesh.Rectangle(2, 2, 0.25f, 0.25f); meshXZ->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(Mathf::HALF_PI, 0.0f, 0.0f)); meshXZ->LocalTransform.SetTranslate(APoint(0.25f, 0.0f, 0.25f)); VertexColor4Material *matXZ = new0 VertexColor4Material(); matXZ->GetAlphaProperty(0, 0)->BlendEnabled = true; matXZ->GetCullProperty(0, 0)->Enabled = false; meshXZ->SetMaterialInstance(matXZ->CreateInstance()); vBufferTemp = meshXZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 1.0f, 0.0f, 0.0f); } nodeXZ->AttachChild(meshXZ); // XYZ node->AttachChild(nodeX); node->AttachChild(nodeY); node->AttachChild(nodeZ); node->AttachChild(nodeXY); node->AttachChild(nodeYZ); node->AttachChild(nodeXZ); return node; }
//---------------------------------------------------------------------------- PX2::Node *GeoObjFactory::CreateRolateCtrl_P() { int axisSamples = 4; int radialSamples = 12; float radial = 0.05f; float height = radial*4.0f; // node PX2::Node *node = new0 Node; node->LocalTransform.SetUniformScale(2.0f); node->SetName("Rolate"); VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC); StandardMesh stdMesh(vf); VertexBuffer *vBufferTemp = 0; VertexBufferAccessor vbaTemp; // x PX2::Node *nodeX = new0 Node; nodeX->SetName("Rolate_X"); VertexBuffer *vBufferX = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaX(vf, vBufferX); vbaX.Position<Float3>(0) = Float3(0.25f, 0.0f, 0.0f); vbaX.Position<Float3>(1) = Float3(1.125f, 0.0f, 0.0f); vbaX.Color<Float4>(0, 0) = Float4::RED; vbaX.Color<Float4>(0, 1) = Float4::RED; vbaX.Position<Float3>(2) = Float3(0.5f, 0.0f, 0.0f); vbaX.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f); vbaX.Color<Float4>(0, 2) = Float4::GREEN; vbaX.Color<Float4>(0, 3) = Float4::GREEN; vbaX.Position<Float3>(4) = Float3(0.5f, 0.0f, 0.0f); vbaX.Position<Float3>(5) = Float3(0.5f, 0.0f, 0.5f); vbaX.Color<Float4>(0, 4) = Float4::RED; vbaX.Color<Float4>(0, 5) = Float4::RED; Polysegment *polysegmentX = new0 PX2::Polysegment(vf, vBufferX, false); polysegmentX->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeX->AttachChild(polysegmentX); TriMesh *meshX = stdMesh.Cylinder(axisSamples, radialSamples, radial, height, false); meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); meshX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y, Mathf::HALF_PI)); meshX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f)); vBufferTemp = meshX->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4::RED; } nodeX->AttachChild(meshX); // y PX2::Node *nodeY = new0 PX2::Node; nodeX->SetName("Rolate_Y"); VertexBuffer *vBufferY = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaY(vf, vBufferY); vbaY.Position<Float3>(0) = Float3(0.0f, 0.25f, 0.0f); vbaY.Position<Float3>(1) = Float3(0.0f, 1.125f, 0.0f); vbaY.Color<Float4>(0, 0) = Float4::GREEN; vbaY.Color<Float4>(0, 1) = Float4::GREEN; vbaY.Position<Float3>(2) = Float3(0.0f, 0.5f, 0.0f); vbaY.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f); vbaY.Color<Float4>(0, 2) = Float4::GREEN; vbaY.Color<Float4>(0, 3) = Float4::GREEN; vbaY.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f); vbaY.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f); vbaY.Color<Float4>(0, 4) = Float4::GREEN; vbaY.Color<Float4>(0, 5) = Float4::GREEN; Polysegment *polysegmentY = new0 PX2::Polysegment(vf, vBufferY, false); polysegmentY->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeY->AttachChild(polysegmentY); TriMesh *meshY = stdMesh.Cylinder(axisSamples, radialSamples, radial, height, false); meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); meshY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X, Mathf::HALF_PI)); meshY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f)); vBufferTemp = meshY->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f); } nodeY->AttachChild(meshY); // z PX2::Node *nodeZ = new0 PX2::Node(); nodeX->SetName("Rolate_Z"); VertexBuffer *vBufferZ = new0 VertexBuffer(6, vf->GetStride()); VertexBufferAccessor vbaZ(vf, vBufferZ); vbaZ.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.25f); vbaZ.Position<Float3>(1) = Float3(0.0f, 0.0f, 1.125f); vbaZ.Color<Float4>(0, 0) = Float4::BLUE; vbaZ.Color<Float4>(0, 1) = Float4::BLUE; vbaZ.Position<Float3>(2) = Float3(0.0f, 0.0f, 0.5f); vbaZ.Position<Float3>(3) = Float3(0.5f, 0.0f, 0.5f); vbaZ.Color<Float4>(0, 2) = Float4::BLUE; vbaZ.Color<Float4>(0, 3) = Float4::BLUE; vbaZ.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.5f); vbaZ.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f); vbaZ.Color<Float4>(0, 4) = Float4::BLUE; vbaZ.Color<Float4>(0, 5) = Float4::BLUE; Polysegment *polysegmentZ = new0 PX2::Polysegment(vf, vBufferZ, false); polysegmentZ->SetMaterialInstance( VertexColor4Material::CreateUniqueInstance()); nodeZ->AttachChild(polysegmentZ); TriMesh *meshZ = stdMesh.Cylinder(axisSamples, radialSamples, radial, height, false); meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance()); meshZ->LocalTransform.SetTranslate(APoint(.0f, 0.0f, 1.125f)); vBufferTemp = meshZ->GetVertexBuffer(); vbaTemp.ApplyTo(vf, vBufferTemp); for (int i = 0; i < vBufferTemp->GetNumElements(); i++) { vbaTemp.Color<Float4>(0, i) = Float4::BLUE; } nodeZ->AttachChild(meshZ); // XYZ node->AttachChild(nodeX); node->AttachChild(nodeY); node->AttachChild(nodeZ); return node; }
//---------------------------------------------------------------------------- bool PolyhedronDistance::ApplyTransform (unsigned char key) { APoint trn; HMatrix rot, incr; float trnSpeed = 0.1f; float rotSpeed = 0.1f; switch (key) { case 'x': trn = mTetras[0]->LocalTransform.GetTranslate(); trn.X() -= trnSpeed; mTetras[0]->LocalTransform.SetTranslate(trn); break; case 'X': trn = mTetras[0]->LocalTransform.GetTranslate(); trn.X() += trnSpeed; mTetras[0]->LocalTransform.SetTranslate(trn); break; case 'y': trn = mTetras[0]->LocalTransform.GetTranslate(); trn.Y() -= trnSpeed; mTetras[0]->LocalTransform.SetTranslate(trn); break; case 'Y': trn = mTetras[0]->LocalTransform.GetTranslate(); trn.Y() += trnSpeed; mTetras[0]->LocalTransform.SetTranslate(trn); break; case 'z': trn = mTetras[0]->LocalTransform.GetTranslate(); trn.Z() -= trnSpeed; mTetras[0]->LocalTransform.SetTranslate(trn); break; case 'Z': trn = mTetras[0]->LocalTransform.GetTranslate(); trn.Z() += trnSpeed; mTetras[0]->LocalTransform.SetTranslate(trn); break; case 's': trn = mTetras[1]->LocalTransform.GetTranslate(); trn.X() -= trnSpeed; mTetras[1]->LocalTransform.SetTranslate(trn); break; case 'S': trn = mTetras[1]->LocalTransform.GetTranslate(); trn.X() += trnSpeed; mTetras[1]->LocalTransform.SetTranslate(trn); break; case 't': trn = mTetras[1]->LocalTransform.GetTranslate(); trn.Y() -= trnSpeed; mTetras[1]->LocalTransform.SetTranslate(trn); break; case 'T': trn = mTetras[1]->LocalTransform.GetTranslate(); trn.Y() += trnSpeed; mTetras[1]->LocalTransform.SetTranslate(trn); break; case 'u': trn = mTetras[1]->LocalTransform.GetTranslate(); trn.Z() -= trnSpeed; mTetras[1]->LocalTransform.SetTranslate(trn); break; case 'U': trn = mTetras[1]->LocalTransform.GetTranslate(); trn.Z() += trnSpeed; mTetras[1]->LocalTransform.SetTranslate(trn); break; case 'a': rot = mTetras[0]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_Y, rotSpeed); mTetras[0]->LocalTransform.SetRotate(incr*rot); break; case 'A': rot = mTetras[0]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_Y, -rotSpeed); mTetras[0]->LocalTransform.SetRotate(incr*rot); break; case 'b': rot = mTetras[1]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_Z, rotSpeed); mTetras[1]->LocalTransform.SetRotate(incr*rot); break; case 'B': rot = mTetras[1]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_Z, -rotSpeed); mTetras[1]->LocalTransform.SetRotate(incr*rot); break; case 'c': rot = mTetras[0]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_X, 1.3f*rotSpeed); mTetras[0]->LocalTransform.SetRotate(incr*rot); rot = mTetras[1]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_Z, -rotSpeed); mTetras[1]->LocalTransform.SetRotate(incr*rot); break; case 'C': rot = mTetras[0]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_X, -1.3f*rotSpeed); mTetras[0]->LocalTransform.SetRotate(incr*rot); rot = mTetras[1]->LocalTransform.GetRotate(); incr.MakeRotation(AVector::UNIT_Z, rotSpeed); mTetras[1]->LocalTransform.SetRotate(incr*rot); break; default: return false; } // Prevent solution point coordinates from being negative. The polyhedron // distance calculator expects solution points to be in the first octant. // Vertices are offset by mOffsetMagnitude*Vector3f(1,1,1) in // UpdateSegments() before the call to the distance routine. Here we make // sure that no translation of a polyhedron takes it so far into one of the // other 7 octants that the offset will not be sufficient to guarantee that // the solution points lie in the first octant. VertexBufferAccessor vba; float threshold = -mOffsetMagnitude + trnSpeed; for (int j = 0; j < 2; ++j) { const APoint& wTrn = mTetras[j]->WorldTransform.GetTranslate(); const HMatrix& wRot = mTetras[j]->WorldTransform.GetRotate(); vba.ApplyTo(mTetras[j]); for (int i = 0; i < 4; i++) { AVector relPosition = vba.Position<Float3>(i); APoint position = wTrn + wRot*relPosition; APoint trn = mTetras[j]->LocalTransform.GetTranslate(); for (int k = 0; k < 3; ++k) { if (position[k] < threshold) { trn[k] += trnSpeed; } } mTetras[j]->LocalTransform.SetTranslate(trn); } } mScene->Update(); UpdateSegments(); return true; }
//---------------------------------------------------------------------------- void PolyhedronDistance::UpdateSegments () { // Two segments make the line easier to see. Vector3f U[2][4]; // Offset the polyhedra so far into the first octant that we are unlikely // to translate them out of that octant during a run. mOffsetMagnitude = 20.0f; Vector3f offset = mOffsetMagnitude*Vector3f::ONE; VertexBufferAccessor vba; int i; for (i = 0; i < 2; ++i) { const APoint& wTrn = mTetras[i]->WorldTransform.GetTranslate(); const HMatrix& wRot = mTetras[i]->WorldTransform.GetRotate(); vba.ApplyTo(mTetras[i]); for (int j = 0; j < 4; ++j) { AVector relPosition = vba.Position<Float3>(j); APoint position = wTrn + wRot*relPosition; U[i][j] = Vector3f(position[0] + offset[0], position[1] + offset[1], position[2] + offset[2]); } } vba.ApplyTo(mSegments[0]); Vector3f vertex[2] = { vba.Position<Vector3f>(0), vba.Position<Vector3f>(1) }; int statusCode; LCPPolyDist3(4, U[0], 4, mFaces, 4, U[1], 4, mFaces, statusCode, mSeparation, vertex); vba.Position<Vector3f>(0) = vertex[0]; vba.Position<Vector3f>(1) = vertex[1]; if ((statusCode != LCPPolyDist3::SC_FOUND_SOLUTION && statusCode != LCPPolyDist3::SC_TEST_POINTS_TEST_FAILED && statusCode != LCPPolyDist3::SC_FOUND_TRIVIAL_SOLUTION) || mSeparation < 0.0f) { // Do not draw the line joining nearest points if returns from // LCPPolyDist are not appropriate. for (i = 0; i < 2; ++i) { vba.Position<Vector3f>(i) = -offset; } } // Correct for the offset and set up endpoints for the segment. for (i = 0; i < 2; ++i) { vba.Position<Vector3f>(i) -= offset; // The adjustment with mSmall "centers" the endpoint tetra on the // solution points. Vector3f temp = vba.Position<Vector3f>(i) - (mSmall/3.0f)*Vector3f::ONE; mTetras[i + 2]->LocalTransform.SetTranslate(temp); } // Double-up the line for better visibility. vertex[0] = vba.Position<Vector3f>(0); vertex[1] = vba.Position<Vector3f>(1); vba.ApplyTo(mSegments[1]); const float epsilon = 0.002f; for (i = 0; i < 2; ++i) { vba.Position<Vector3f>(i) = vertex[i] + epsilon*Vector3f::ONE; } for (i = 0; i < 2; ++i) { mSegments[i]->UpdateModelSpace(Visual::GU_MODEL_BOUND_ONLY); mSegments[i]->Update(); mRenderer->Update(mSegments[i]->GetVertexBuffer()); } mScene->Update(); }