?? cvshapes.cpp
字號:
int numFacesAdded;
ChNrMeshAddFaces(mesh,
numVerts,
(ChNrVector*) v,
numNorms,
(ChNrVector*) n,
face_data,
&numFacesAdded,
&facesAdded);
#if defined(CH_USE_D3D)
numFacesAdded = facesAdded->GetSize();
#endif
// Assign colors to faces
int iface = 0;
ChNrFace elt;
if(pNode->parts.value & QvCylinder::TOP)
{
int count = 1; // count
if(!boolCull) count *= 2;
for( int j = 0; j < count; j ++)
{
GetElement(facesAdded, unsigned(iface), elt);
if(boolUseTexture)
SetTextureCoordinates(pTxMap, mesh, elt, Top);
materialMap.Set(mesh, elt, ChQvCylinderMaterials::Top);
D3DRelease(elt);
iface++;
}
}
// Do the bottom
if(pNode->parts.value & QvCylinder::BOTTOM)
{
int count = 1; // count
if(!boolCull) count *= 2;
for( int j = 0; j < count; j ++)
{
GetElement(facesAdded, unsigned(iface), elt);
if(boolUseTexture)
SetTextureCoordinates(pTxMap, mesh, elt, Bottom);
materialMap.Set(mesh, elt, ChQvCylinderMaterials::Bottom);
D3DRelease(elt);
iface++;
}
}
// Do the sides
if(pNode->parts.value & QvCylinder::SIDES)
{
int count = numFacets; // count
if(!boolCull) count *= 2;
for( int j = 0; j < count; j ++)
{
GetElement(facesAdded, unsigned(iface), elt);
if(boolUseTexture && j < numFacets)
SetTextureCoordinates(pTxMap, mesh, elt, Sides, j % numFacets);
materialMap.Set(mesh, elt, ChQvCylinderMaterials::Sides);
D3DRelease(elt);
iface++;
}
}
if(boolUseTexture)
{
ChTextureHandle hdl = pTextureData->GetTextureHandle();
if(hdl)
{
// Texture guy got here first, apply it
//ChNrMeshSetTexture(mesh, hdl);
SetTexture(pTextureData);
}
}
// Cleanup time
ChNrFree(facesAdded);
delete [] v;
delete [] n;
delete [] face_data;
delete pTxMap;
pIterator->DidAShape();
pRC->UnlockScene();
pRC->UnlockQv(); // Unlock tree
}
#endif
return true;
}
bool ChQvCylinderInstance::Draw(ChRenderContext *pRC, ChDrawIterator *pIterator)
{
#if defined( CH_USE_3DR )
{
Fixed32_t On = 1;
Fixed32_t Off = 0;
G3dHandle_t hGC = pRC->GetGC();
Dword_t hRC = pRC->GetRC();
QvCylinder *pNode = (QvCylinder *)GetNode();
pRC->SetModelTransform(GetTransform());
pRC->SetShading(this);
Float_t cull = 0;
Fixed32_t wMattNum = 0; // always use material 0
if(pNode->parts.value == QvCylinder::ALL) cull = 1; // if all sides are present, then cull
G3dSetMatt( hGC, wMattNum, G3DM_BACK_CULL, (Float_t *)&cull );
int numFacets = CalcCylinderFacetCount(this, state);
// Make a material mapping; we will use later for each facet, top and bottom
ChQvCylinderMaterials materialMap( this );
/* Do the texture stuff - find it, make the map, set up 3dr for it, */
int boolUseTexture = SetupTexture(pRC);
ChQvCylinderTextures *pTxMap = 0;
if(boolUseTexture)
{
pTxMap = new ChQvCylinderTextures( this, numFacets );
}
float h2 = pNode->height.value / 2.;
float r = pNode->radius.value;
Fixed32_t lCCW;
G3dGetState( hGC, G3DL_FRONT_CCW, &lCCW); // save CCW state
G3dSetState( hGC, G3DL_FRONT_CCW, &On);
bool boolPureEmissive;
float pi = atan(1.) * 4.;
float twoPi = pi * 2;
// Do the sides
if(pNode->parts.value & QvCylinder::SIDES)
{
materialMap.Set(hRC, hGC, 0, &boolPureEmissive);
pRC->SetModulation( boolUseTexture, boolPureEmissive);
G3dBeginPrim(hGC, G3D_PRM_QUADSTRIP, numFacets * 2 + 2);
for( int facet = 0; facet <= numFacets; facet ++)
{
PointF_t n, v1, v2;
float theta = facet * twoPi / numFacets;
n.x = -sin(theta);
n.y = 0;
n.z = -cos(theta);
v1.x = n.x * r;
v1.y = h2;
v1.z = n.z * r;
v2 = v1;
v2.y = -h2;
if(boolUseTexture)
{
PointF_t textCoord = pTxMap->GetCoord3(0, facet, 0);
G3dAddPrimVtxF(hGC, &v1, &n, &textCoord, 0);
textCoord = pTxMap->GetCoord3(0, facet, 1);
G3dAddPrimVtxF(hGC, &v2, &n, &textCoord, 0);
}
else
{
G3dAddPrimVtxF(hGC, &v1, &n, 0, 0);
G3dAddPrimVtxF(hGC, &v2, &n, 0, 0);
}
}
G3dEndPrim(hGC);
}
G3dSetState( hGC, G3DL_FRONT_CCW, &On);
// Do the top
if(pNode->parts.value & QvCylinder::TOP)
{
materialMap.Set(hRC, hGC, 1 /*top*/, &boolPureEmissive);
pRC->SetModulation( boolUseTexture, boolPureEmissive);
G3dBeginPrim(hGC, G3D_PRM_POLYGON, numFacets);
PointF_t n, v1;
n.x = 0;
n.y = 1;
n.z = 0;
for( int j = 0; j <= numFacets; j ++)
{
float theta = j * twoPi / numFacets;
v1.x = -sin(theta) * r;
v1.y = h2;
v1.z = -cos(theta) * r;
if(boolUseTexture)
{
PointF_t textCoord = pTxMap->GetCoord3(1, 0, j);
G3dAddPrimVtxF(hGC, &v1, &n, &textCoord, 0);
}
else
{
G3dAddPrimVtxF(hGC, &v1, &n, 0, 0);
}
}
G3dEndPrim(hGC);
}
// Do the bottom
G3dSetState( hGC, G3DL_FRONT_CCW, &Off);
if(pNode->parts.value & QvCylinder::BOTTOM)
{
materialMap.Set(hRC, hGC, 2 /*bottom*/, &boolPureEmissive);
pRC->SetModulation( boolUseTexture, boolPureEmissive);
G3dBeginPrim(hGC, G3D_PRM_POLYGON, numFacets);
PointF_t n, v1;
n.x = 0;
n.y = -1;
n.z = 0;
for( int j = 0; j <= numFacets; j ++)
{
float theta = j * twoPi / numFacets;
v1.x = sin(theta + pi) * r;
v1.y = -h2;
v1.z = cos(theta + pi) * r;
if(boolUseTexture)
{
PointF_t textCoord = pTxMap->GetCoord3(2, 0, j);
G3dAddPrimVtxF(hGC, &v1, &n, &textCoord, 0);
}
else
{
G3dAddPrimVtxF(hGC, &v1, &n, 0, 0);
}
}
G3dEndPrim(hGC);
}
G3dSetState( hGC, G3DL_FRONT_CCW, &lCCW);
if(boolUseTexture)
{
pRC->SetTexture(0); // turn off texture
delete pTxMap;
}
}
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
#endif //defined( CH_USE_3DR )
return true;
}
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
void ChQvCylinderInstance::SetTextureCoordinates(ChQvCylinderTextures *pTxMap, ChNrMesh mesh, ChNrFace face, Parts part, int facet)
{
int count = ChNrFaceGetVertexCount(face);
for(int j = 0; j < count; j++)
{
GxVec3f textCoord = pTxMap->GetCoord3(part, facet, j);
int index = ChNrFaceGetVertexIndex(face, j);
ChNrMeshSetTextureCoordinates(mesh, index, textCoord.x(), textCoord.y());
}
}
#endif
ChQvIFSInstance::ChQvIFSInstance() : ChQvShapeInstance()
{
}
#define ALMOST_ZERO (1.e-12)
bool ChQvIFSInstance::IsConvex(int iFirstVertex, int iNumVerts)
{
QvIndexedFaceSet *pNode = (QvIndexedFaceSet *)GetNode();
// If they claim convex, believe 'em
if(GetShapeHints()->faceType.value == QvShapeHints::CONVEX) return true;
QvCoordinate3 *pC3 = GetCoordinate3();
int j;
GxVec3f n;
long *pCoords = pNode->coordIndex.values + iFirstVertex;
// First pass - find a non-degenerate normal
for(j = 0; j < iNumVerts; j++)
{
int iC3 = pCoords[j] * 3;
GxVec3f p(pC3->point.values[iC3], pC3->point.values[iC3+1], pC3->point.values[iC3+2]);
int iCv = pCoords[(j+1) % iNumVerts] * 3;
GxVec3f v1(pC3->point.values[iCv], pC3->point.values[iCv+1], pC3->point.values[iCv+2]);
iCv = pCoords[(j+2) % iNumVerts] * 3;
GxVec3f v2(pC3->point.values[iCv], pC3->point.values[iCv+1], pC3->point.values[iCv+2]);
v1 -= p;
v2 -= p;
n = v1.cross(v2);
if(n.magnitude() > ALMOST_ZERO) break;
}
GxVec3f nRef = n;
// Second pass - test against non-degenerate reference normal
for(j = 0; j < iNumVerts; j++)
{
int iC3 = pCoords[j] * 3;
GxVec3f p(pC3->point.values[iC3], pC3->point.values[iC3+1], pC3->point.values[iC3+2]);
int iCv = pCoords[(j+1) % iNumVerts] * 3;
GxVec3f v1(pC3->point.values[iCv], pC3->point.values[iCv+1], pC3->point.values[iCv+2]);
iCv = pCoords[(j+2) % iNumVerts] * 3;
GxVec3f v2(pC3->point.values[iCv], pC3->point.values[iCv+1], pC3->point.values[iCv+2]);
v1 -= p;
v2 -= p;
n = v1.cross(v2);
if(n.dot(nRef) < 0.0) return false;
}
return true; // TODO
};
bool ChQvIFSInstance::Construct(ChRenderContext *pRC, ChConstructionIterator *pIterator)
{
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
{
ASSERT(m_frame );
pRC->LockQv(); // Lock tree so other threads don't kill our data
if(!pIterator->IsOKToProceed(this)) // This locks scene if available
{
pRC->UnlockQv(); // Unlock tree
return 0;
}
if(IsConstructed())
{
pRC->UnlockQv(); // Lock tree so other threads don't kill our data
pRC->UnlockScene();
return 1;
}
//TRACE("Constructing an IFS\n");
m_boolConstructed = true;
QvIndexedFaceSet *pNode = (QvIndexedFaceSet *)GetNode();
// Interpret shapehints; we assume there is at least one there; (we inited to make sure)
// Remember that RL CW is opposite from VRML (LHS ~ RHS)
bool boolCCW = (GetShapeHints()->vertexOrdering.value == QvShapeHints::COUNTERCLOCKWISE);
bool boolDirectionKnown = !(GetShapeHints()->vertexOrdering.value == QvShapeHints::UNKNOWN_ORDERING);
bool boolFlipNormals = false; // ????????
// Figure out if we can backcull. solid + known order means we can
bool boolBackCull = ((GetShapeHints()->vertexOrdering.value != QvShapeHints::UNKNOWN_ORDERING) &&
(GetShapeHints()->shapeType.value == QvShapeHints::SOLID));
/* If they can't write good nodes, don't draw them! */
if(((ChQvIFSRenderData *)m_pRenderData)->IsValid())
{
ChQvIndexedFaceSetNormals *pNormals = ((ChQvIFSRenderData *)m_pRenderData)->GetNormals();
// Make a material mapping; we will use later for each face
ChQvFaceSetMaterials materialMap( this );
pRC->AdjustTransparency(materialMap);
int j; // multiuse counter
/* Get the texture map, */
ChQvIFSTextures *pTxMap = new ChQvIFSTextures( this );
ChQvTextureRenderData *pTextureData = (ChQvTextureRenderData*)(GetTexture2()->GetRenderData());
bool boolUseTexture = !(pTextureData->IsEmpty()); // one -might- arrive
// Get the vertices
QvCoordinate3 *pC3 = GetCoordinate3();
ChNrMesh mesh = m_mesh = pRC->CreateMesh();
ChNrFrameAddVisual(GetFrame(), mesh);
D3DRelease(mesh);
ChNrObjectSetAppData(mesh, (unsigned long)this);
ChNrMeshSetPerspective(mesh,true);
QvMaterialBinding::Binding binding = (QvMaterialBinding::Binding)(GetMaterialBinding()->value.value);
bool boolColorByFace = !(binding == QvMaterialBinding::PER_VERTEX ||
binding == QvMaterialBinding::PER_VERTEX_INDEXED);
ChNrMeshSetColorSource(mesh, boolColorByFace ? ColorFromFace : ColorFromVertex);
// Need to reserve space for vertices, normals, and faces - ????
int numFaces = GetFaceCount(pNode->coordIndex.values, pNode->coordIndex.num);
// Allocate vertex and normal arrays, at least as big as we need
int normSize = pNode->coordIndex.num;
if(!boolBackCull) normSize *= 2;
GxVec3f *pN = new GxVec3f[normSize];
GxVec3f *pV = new GxVec3f[pNode->coordIndex.num];
// Allocate the index arrays, to reuse as much as possible
int * faceNorms = new int[numFaces];
int * uniqueNorms = new int[pNode->coordIndex.num]; // indexed by coord #
int * sharedNorms = new int[pC3->point.num]; // indexed by coordIndex[j]
int * verts = new int[pC3->point.num];
int * texIndices = new int[pC3->point.num]; // parallel to verts
int * texVerts = new int[pNode->coordIndex.num]; // indexed by coord #
for( j = 0; j< pNode->coordIndex.num; j++)
{
uniqueNorms[j] = -1; // -1 unused
}
for( j = 0; j< pC3->point.num; j++)
{
sharedNorms[j] = verts[j] = -1; // -1 unused
}
for( j = 0; j< numFaces; j++)
{
faceNorms[j] = -1; // -1 unused
}
// Get the coordinates; add all the vertices and normals to the mesh, and index them
// Counters into faces, pN and pV
int numN = 0; // pN
int numV = 0; // pV
int iface = 0; // current face
int ifd = 0; // Index to Face Data
int face_data_size = pNode->coordIndex.num * 2 // for faces' vertices
+ numFaces // face counts
+ 1; // terminator
if(!boolBackCull) face_data_size *= 2;
// As a worst case, we could get a triangle for almost
// every point. To be conservative, we assume this and get
// lots of space for face_data
face_data_size *= 4; // actually need 7 ints for each triangle, instead of 2
ChNrFaceData * face_data = new ChNrFaceData[face_data_size];
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -