//------------------------------------------------------------------------------ // // CRegionView::DoCreatePrimitivePyramid // // Creates a brush in the shape of a pyramid. // //------------------------------------------------------------------------------ void CRegionView::DoCreatePrimitivePyramid( CVector &vCenter, int nNumSides, CReal fHeight, CReal fRadius ) { CWorldNode *pParent; CEditBrush *pNewBrush; CMoArray<CEditPoly *> pNewPoly; CPolyRef polyRef; CVertRefArray newVerts; DWORD i; CMoArray<CEditVert> vEditVerts; CMatrix matRot; CVector vRotationVector; vRotationVector.Init( 0.0f, 1.0f, 0.0f ); ASSERT( nNumSides >= 3 ); //ASSERT( nNumSides <= 24 ); if( nNumSides < 3 )//|| 24 < nNumSides ) return; pNewPoly.SetSize(nNumSides + 1); vEditVerts.SetSize(nNumSides + 2); // Setup a new brush and a new starting poly... pNewBrush = no_CreateNewBrush(GetRegion(), GetRegion()->GetActiveParentNode()); ASSERT( pNewBrush ); if( !pNewBrush ) return; // Setup an undo. GetRegionDoc()->Modify(new CPreAction(ACTION_ADDEDNODE, pNewBrush), TRUE); for( i = 0; i <= nNumSides; i++ ) { pNewPoly[i] = new CEditPoly( pNewBrush ); ASSERT( pNewPoly[i] ); if( !pNewPoly[i] ) { delete pNewBrush; return; } } // Make base points... vEditVerts[0].Init( vCenter.x, vCenter.y - fHeight/2, vCenter.z + fRadius ); pNewBrush->m_Points.Append( vEditVerts[0] ); gr_SetupRotationAroundVector(&matRot, vRotationVector, -MATH_CIRCLE / nNumSides); for( i = 1; i < nNumSides; i++ ) { vEditVerts[i] = vEditVerts[i-1]; vEditVerts[i] -= vCenter; matRot.Apply( vEditVerts[i] ); vEditVerts[i] += vCenter; pNewBrush->m_Points.Append( vEditVerts[i] ); } // Make top point... vEditVerts[nNumSides].Init( vCenter.x, vCenter.y + fHeight/2, vCenter.z ); pNewBrush->m_Points.Append( vEditVerts[nNumSides] ); // Make base poly for( i = 0; i < nNumSides; i++ ) { pNewPoly[0]->m_Indices.Append( i ); } // Set normal... pNewPoly[0]->Normal().Init( 0.0f, -1.0f, 0.0f ); pNewPoly[0]->Dist() = pNewPoly[0]->Normal().Dot( pNewPoly[0]->Pt(0) ); pNewBrush->m_Polies.Append( pNewPoly[0] ); // Make side poly's for( i = 0; i < nNumSides; i++ ) { pNewPoly[i+1]->m_Indices.Append(i ); pNewPoly[i+1]->m_Indices.Append(nNumSides ); pNewPoly[i+1]->m_Indices.Append(( i + 1 ) % nNumSides ); pNewBrush->m_Polies.Append( pNewPoly[i+1] ); } GetRegion()->UpdateBrushGeometry(pNewBrush); GetRegion()->CleanupGeometry(); // Setup the node stuff. // SetupBrushProperties(pNewBrush, GetRegion()); // Make the new brush the selection. if( GetMainFrame()->GetNodeSelectionMode() != MULTI_SELECTION ) GetRegion()->ClearSelections(); GetRegion()->SelectNode( pNewBrush->AsNode() ); GetRegionDoc()->NotifySelectionChange(); GetRegionDoc()->RedrawAllViews(); }
//------------------------------------------------------------------------------ // // CRegionView::DoCreatePrimitiveCylinder // // Creates a brush in the shape of a cylinder. // //------------------------------------------------------------------------------ void CRegionView::DoCreatePrimitiveCylinder( CVector &vCenter, int nNumSides, CReal fHeight, CReal fRadius ) { CWorldNode *pParent; CEditBrush *pNewBrush; CEditPoly *pNewPoly; CReal fHalfHeight; CPolyRef polyRef; CVertRefArray newVerts; DWORD i; CEditVert vEditVerts[32]; CMatrix matRot; CVector vRotationVector; vRotationVector.Init( 0.0f, 1.0f, 0.0f ); ASSERT( nNumSides >= 3 ); ASSERT( nNumSides <= 32 ); if( nNumSides < 3 || 32 < nNumSides ) return; fHalfHeight = fHeight / 2.0f; // Setup a new brush and a new starting poly... pNewBrush = no_CreateNewBrush(GetRegion(), GetRegion()->GetActiveParentNode()); ASSERT( pNewBrush ); if( !pNewBrush ) return; // Setup an undo. GetRegionDoc()->Modify(new CPreAction(ACTION_ADDEDNODE, pNewBrush), TRUE); pNewPoly = new CEditPoly( pNewBrush ); ASSERT( pNewPoly ); if( !pNewPoly ) { delete pNewBrush; return; } pNewBrush->m_Polies.Append( pNewPoly ); vEditVerts[0].Init( vCenter.x, vCenter.y + fHalfHeight, vCenter.z + fRadius ); gr_SetupRotationAroundVector(&matRot, vRotationVector, MATH_CIRCLE / nNumSides); for( i = 1; i < nNumSides; i++ ) { vEditVerts[i] = vEditVerts[i-1]; vEditVerts[i] -= vCenter; matRot.Apply( vEditVerts[i] ); vEditVerts[i] += vCenter; } // Make top of brush for( i = 0; i < nNumSides; i++ ) { pNewPoly->m_Indices.Append( i ); pNewBrush->m_Points.Append( vEditVerts[i] ); } // Set normal... pNewPoly->Normal().Init( 0.0f, 1.0f, 0.0f ); pNewPoly->Dist() = pNewPoly->Normal().Dot( pNewPoly->Pt(0) ); // Extrude... polyRef.Init( pNewBrush, 0 ); if( ExtrudePoly( polyRef, newVerts, FALSE, TRUE /*flip all*/) ) { CEditVert *pVert; pVert = &newVerts[0]( ); for( i = 0; i < nNumSides; i++ ) { newVerts[i]() -= polyRef()->Normal() * fHeight; } for( DWORD j=0; j < pNewBrush->m_Polies; j++ ) { pNewBrush->m_Polies[j]->UpdatePlane(); for(uint32 nCurrTex = 0; nCurrTex < CEditPoly::NUM_TEXTURES; nCurrTex++) pNewBrush->m_Polies[j]->SetupBaseTextureSpace(nCurrTex); } } GetRegion()->UpdateBrushGeometry(pNewBrush); GetRegion()->CleanupGeometry(); // Setup the node stuff. // SetupBrushProperties(pNewBrush, GetRegion()); // Make the new brush the selection. if( GetMainFrame()->GetNodeSelectionMode() != MULTI_SELECTION ) GetRegion()->ClearSelections(); GetRegion()->SelectNode( pNewBrush->AsNode() ); GetRegionDoc()->NotifySelectionChange(); GetRegionDoc()->RedrawAllViews(); }