//---------------------------------------------------------------------------- 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. }
//---------------------------------------------------------------------------- void ReflectionsAndShadows::CopyNormalToTCoord1 (Object* object) { TriMesh* mesh = DynamicCast<TriMesh>(object); if (mesh) { VertexBufferAccessor vba(mesh); for (int i = 0; i < vba.GetNumVertices(); ++i) { vba.TCoord<Vector3f>(1, i) = vba.Normal<Vector3f>(i); } mRenderer->Update(mesh->GetVertexBuffer()); } Node* node = DynamicCast<Node>(object); if (node) { for (int i = 0; i < node->GetNumChildren(); ++i) { Spatial* child = node->GetChild(i); if (child) { CopyNormalToTCoord1(child); } } } }
//---------------------------------------------------------------------------- void GelatinCube::PhysicsTick () { mModule->Update((float)GetTimeInSeconds()); // Update spline surface. Remember that the spline maintains its own // copy of the control points, so this update is necessary. int numSlices = mModule->GetNumSlices() - 2; int numRows = mModule->GetNumRows() - 2; int numCols = mModule->GetNumCols() - 2; for (int s = 0; s < numSlices; ++s) { for (int r = 0; r < numRows; ++r) { for (int c = 0; c < numCols; ++c) { mSpline->SetControlPoint(c, r, s, mModule->Position(s + 1, r + 1, c + 1)); } } } mBox->UpdateSurface(); for (int i = 0; i < mBox->GetNumChildren(); ++i) { TriMesh* mesh = StaticCast<TriMesh>(mBox->GetChild(i)); mRenderer->Update(mesh->GetVertexBuffer()); } }
//---------------------------------------------------------------------------- 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()); }
//---------------------------------------------------------------------------- RawTerrainPage::RawTerrainPage (VertexFormat* vformat, int size, float* heights, const Float2& origin, float spacing) : mSize(size), mSizeM1(size - 1), mHeights(heights), mOrigin(origin), mSpacing(spacing) { // size = 2^p + 1, p <= 7 assertion(size == 3 || size == 5 || size == 9 || size == 17 || size == 33 || size == 65 || size == 129, "Invalid page size\n"); mInvSpacing = 1.0f/mSpacing; // 创建地形页网格 float ext = mSpacing*mSizeM1; TriMesh* mesh = StandardMesh(vformat).Rectangle(mSize, mSize, ext, ext); mVFormat = vformat; mVBuffer = mesh->GetVertexBuffer(); mIBuffer = mesh->GetIndexBuffer(); delete0(mesh); // 修改地形顶点数据 VertexBufferAccessor vba(mVFormat, mVBuffer); int numVertices = mVBuffer->GetNumElements(); for (int i = 0; i < numVertices; ++i) { int x = i % mSize; int y = i / mSize; vba.Position<Float3>(i) = Float3(GetX(x), GetY(y), GetHeight(i)); vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, 1.0f); } UpdateModelSpace(Renderable::GU_NORMALS); mUV01 = Float4(8.0f, 8.0f, 8.0f, 8.0f); mUV23 = Float4(8.0f, 8.0f, 8.0f, 8.0f); mUV4 = Float4(8.0f, 8.0f, 8.0f, 8.0f); mUV01Float = new0 ShaderFloat(1); mUV23Float = new0 ShaderFloat(1); mUV4Float = new0 ShaderFloat(1); SetUV0(Float2(mUV01[0], mUV01[1])); SetUV1(Float2(mUV01[2], mUV01[3])); SetUV2(Float2(mUV23[0], mUV23[1])); SetUV3(Float2(mUV23[2], mUV23[3])); SetUV4(Float2(mUV4[0], mUV4[1])); mTextureAlpha = new0 Texture2D(Texture::TF_A8R8G8B8, mSize, mSize, 1); mTextureDefault = DynamicCast<Texture2D>(ResourceManager::GetSingleton() .BlockLoad("Data/Images/Terrain/NiTu.dds")); assertion(mTextureDefault!=0, "Load texture %s failed.", "Data/Images/Terrain/NiTu.dds"); }
//---------------------------------------------------------------------------- RevolutionSurface::RevolutionSurface (Curve2f* curve, float xCenter, TopologyType topology, int numCurveSamples, int numRadialSamples, bool sampleByArcLength, bool outsideView, VertexFormat* vformat) : mCurve(curve), mXCenter(xCenter), mTopology(topology), mNumCurveSamples(numCurveSamples), mNumRadialSamples(numRadialSamples), mSin(0), mCos(0), mSamples(0), mSampleByArcLength(sampleByArcLength) { ComputeSampleData(); // The topology of the meshes is all that matters. The vertices will be // modified later based on the curve of revolution. StandardMesh stdmesh(vformat, !outsideView); TriMesh* mesh = 0; switch (mTopology) { case REV_DISK_TOPOLOGY: mesh = stdmesh.Disk(mNumCurveSamples, mNumRadialSamples, 1.0f); break; case REV_CYLINDER_TOPOLOGY: mesh = stdmesh.Cylinder(mNumCurveSamples, mNumRadialSamples, 1.0f, 1.0f, true); break; case REV_SPHERE_TOPOLOGY: mesh = stdmesh.Sphere(mNumCurveSamples, mNumRadialSamples, 1.0f); break; case REV_TORUS_TOPOLOGY: mesh = stdmesh.Torus(mNumCurveSamples, mNumRadialSamples, 1.0f, 0.25f); break; default: assertion(false, "Unexpected condition\n"); break; } assertion(mesh != 0, "Failed to construct mesh\n"); mVFormat = vformat; mVBuffer = mesh->GetVertexBuffer(); // Generate the actual surface by replacing the vertex values. NOTE: // Setting mIBuffer to zero acts as a flag that tells UpdateSurface // *not* to call Renderer::UpdateVertexBuffer(mVBuffer). Only when the // application has constructed a RevolutionSurface wlil the update occur. mIBuffer = 0; UpdateSurface(); mIBuffer = mesh->GetIndexBuffer(); delete0(mesh); }
//---------------------------------------------------------------------------- RawTerrainPage::RawTerrainPage (VertexFormat* vformat, int size, float* heights, const Float2& origin, float spacing) : TerrainPage(size, heights, origin, spacing) { float ext = mSpacing*mSizeM1; TriMesh* mesh = StandardMesh(vformat).Rectangle(mSize, mSize, ext, ext); mVFormat = vformat; mVBuffer = mesh->GetVertexBuffer(); mIBuffer = mesh->GetIndexBuffer(); delete0(mesh); VertexBufferAccessor vba(mVFormat, mVBuffer); int numVertices = mVBuffer->GetNumElements(); for (int i = 0; i < numVertices; ++i) { int x = i % mSize; int y = i / mSize; vba.Position<Float3>(i) = Float3(GetX(x), GetY(y), GetHeight(i)); vba.Normal<Float3>(i) = Float3(0.0f, 0.0f, 1.0f); vba.Color<Float3>(0, i) = Float3(0.0f, 0.0f, 0.0f); } UpdateModelSpace(Renderable::GU_NORMALS); mUV01 = Float4(8.0f, 8.0f, 8.0f, 8.0f); mUV23 = Float4(8.0f, 8.0f, 8.0f, 8.0f); mUV4 = Float4(8.0f, 8.0f, 8.0f, 8.0f); mUV01Float = new0 ShaderFloat(1); mUV23Float = new0 ShaderFloat(1); mUV4Float = new0 ShaderFloat(1); SetUV0(Float2(mUV01[0], mUV01[1])); SetUV1(Float2(mUV01[2], mUV01[3])); SetUV2(Float2(mUV23[0], mUV23[1])); SetUV3(Float2(mUV23[2], mUV23[3])); SetUV4(Float2(mUV4[0], mUV4[1])); mTextureAlpha = new0 Texture2D(Texture::TF_A8R8G8B8, mSize, mSize, 1); mTextureDefaultFilename = "Data/engine/grass.png"; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- TriMesh* StandardMesh::Cylinder (int axisSamples, int radialSamples, float radius, float height, bool open) { TriMesh* mesh; int unit; Float2 tcoord; if (open) { int numVertices = axisSamples*(radialSamples+1); int numTriangles = 2*(axisSamples-1)*radialSamples; int numIndices = 3*numTriangles; int stride = mVFormat->GetStride(); // Create a vertex buffer. VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, stride, mUsage); VertexBufferAccessor vba(mVFormat, vbuffer); // Generate geometry. float invRS = 1.0f/(float)radialSamples; float invASm1 = 1.0f/(float)(axisSamples-1); float halfHeight = 0.5f*height; int r, a, aStart, i; // Generate points on the unit circle to be used in computing the // mesh points on a cylinder slice. float* cs = new1<float>(radialSamples + 1); float* sn = new1<float>(radialSamples + 1); for (r = 0; r < radialSamples; ++r) { float angle = Mathf::TWO_PI*invRS*r; cs[r] = Mathf::Cos(angle); sn[r] = Mathf::Sin(angle); } cs[radialSamples] = cs[0]; sn[radialSamples] = sn[0]; // Generate the cylinder itself. for (a = 0, i = 0; a < axisSamples; ++a) { float axisFraction = a*invASm1; // in [0,1] float z = -halfHeight + height*axisFraction; // Compute center of slice. APoint sliceCenter(0.0f, 0.0f, z); // Compute slice vertices with duplication at endpoint. int save = i; for (r = 0; r < radialSamples; ++r) { float radialFraction = r*invRS; // in [0,1) AVector normal(cs[r], sn[r], 0.0f); vba.Position<Float3>(i) = sliceCenter + radius*normal; if (mHasNormals) { if (mInside) { vba.Normal<Float3>(i) = -normal; } else { vba.Normal<Float3>(i) = normal; } } tcoord = Float2(radialFraction, axisFraction); for (unit = 0; unit < MAX_UNITS; ++unit) { if (mHasTCoords[unit]) { vba.TCoord<Float2>(unit, i) = tcoord; } } ++i; } vba.Position<Float3>(i) = vba.Position<Float3>(save); if (mHasNormals) { vba.Normal<Float3>(i) = vba.Normal<Float3>(save); } tcoord = Float2(1.0f, axisFraction); for (unit = 0; unit < MAX_UNITS; ++unit) { if (mHasTCoords[unit]) { vba.TCoord<Float2>(0, i) = tcoord; } } ++i; } TransformData(vba); // Generate indices. IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, 4, mUsage); int* indices = (int*)ibuffer->GetData(); for (a = 0, aStart = 0; a < axisSamples-1; ++a) { int i0 = aStart; int i1 = i0 + 1; aStart += radialSamples + 1; int i2 = aStart; int i3 = i2 + 1; for (i = 0; i < radialSamples; ++i, indices += 6) { if (mInside) { indices[0] = i0++; indices[1] = i2; indices[2] = i1; indices[3] = i1++; indices[4] = i2++; indices[5] = i3++; } else // outside view { indices[0] = i0++; indices[1] = i1; indices[2] = i2; indices[3] = i1++; indices[4] = i3++; indices[5] = i2++; } } } delete1(cs); delete1(sn); mesh = new0 TriMesh(mVFormat, vbuffer, ibuffer); } else { mesh = Sphere(axisSamples, radialSamples, radius); VertexBuffer* vbuffer = mesh->GetVertexBuffer(); int numVertices = vbuffer->GetNumElements(); VertexBufferAccessor vba(mVFormat, vbuffer); // Flatten sphere at poles. float hDiv2 = 0.5f*height; vba.Position<Float3>(numVertices-2)[2] = -hDiv2; // south pole vba.Position<Float3>(numVertices-1)[2] = +hDiv2; // north pole // Remap z-values to [-h/2,h/2]. float zFactor = 2.0f/(axisSamples-1); float tmp0 = radius*(-1.0f + zFactor); float tmp1 = 1.0f/(radius*(+1.0f - zFactor)); for (int i = 0; i < numVertices-2; ++i) { Float3& pos = vba.Position<Float3>(i); pos[2] = hDiv2*(-1.0f + tmp1*(pos[2] - tmp0)); float adjust = radius*Mathf::InvSqrt(pos[0]*pos[0] + pos[1]*pos[1]); pos[0] *= adjust; pos[1] *= adjust; } TransformData(vba); if (mHasNormals) { mesh->UpdateModelSpace(Visual::GU_NORMALS); } } // The duplication of vertices at the seam causes the automatically // generated bounding volume to be slightly off center. Reset the bound // to use the true information. float maxDist = Mathf::Sqrt(radius*radius + height*height); mesh->GetModelBound().SetCenter(APoint::ORIGIN); mesh->GetModelBound().SetRadius(maxDist); return mesh; }
//---------------------------------------------------------------------------- void BoxSurface::UpdateSurface () { int permute[3]; TriMesh* mesh; VertexFormat* vformat; VertexBuffer* vbuffer; // u faces permute[0] = 1; permute[1] = 2; permute[2] = 0; // u = 0 mesh = StaticCast<TriMesh>(GetChild(0)); vformat = mesh->GetVertexFormat(); vbuffer = mesh->GetVertexBuffer(); UpdateFace(mNumWSamples, mNumVSamples, vformat, vbuffer, false, 0.0f, permute); mesh->UpdateModelSpace(Renderable::GU_NORMALS); Renderer::UpdateAll(vbuffer); // u = 1 mesh = StaticCast<TriMesh>(GetChild(1)); vformat = mesh->GetVertexFormat(); vbuffer = mesh->GetVertexBuffer(); UpdateFace(mNumWSamples, mNumVSamples, vformat, vbuffer, true, 1.0f, permute); mesh->UpdateModelSpace(Renderable::GU_NORMALS); Renderer::UpdateAll(vbuffer); // v faces permute[0] = 0; permute[1] = 2; permute[2] = 1; // v = 0 mesh = StaticCast<TriMesh>(GetChild(2)); vformat = mesh->GetVertexFormat(); vbuffer = mesh->GetVertexBuffer(); UpdateFace(mNumWSamples, mNumUSamples, vformat, vbuffer, true, 0.0f, permute); mesh->UpdateModelSpace(Renderable::GU_NORMALS); Renderer::UpdateAll(vbuffer); // v = 1 mesh = StaticCast<TriMesh>(GetChild(3)); vformat = mesh->GetVertexFormat(); vbuffer = mesh->GetVertexBuffer(); UpdateFace(mNumWSamples, mNumUSamples, vformat, vbuffer, false, 1.0f, permute); mesh->UpdateModelSpace(Renderable::GU_NORMALS); Renderer::UpdateAll(vbuffer); // w faces permute[0] = 0; permute[1] = 1; permute[2] = 2; // w = 0 mesh = StaticCast<TriMesh>(GetChild(4)); vformat = mesh->GetVertexFormat(); vbuffer = mesh->GetVertexBuffer(); UpdateFace(mNumVSamples, mNumUSamples, vformat, vbuffer, false, 0.0f, permute); mesh->UpdateModelSpace(Renderable::GU_NORMALS); Renderer::UpdateAll(vbuffer); // w = 1 mesh = StaticCast<TriMesh>(GetChild(5)); vformat = mesh->GetVertexFormat(); vbuffer = mesh->GetVertexBuffer(); UpdateFace(mNumVSamples, mNumUSamples, vformat, vbuffer, true, 1.0f, permute); mesh->UpdateModelSpace(Renderable::GU_NORMALS); Renderer::UpdateAll(vbuffer); }