?? cvshapes.cpp
字號:
int ifd = 0; // index into face data
GxVec3f *n = new GxVec3f[numNorms], *v = new GxVec3f[numVerts];
for (int index = 0; index < numVerts; index++)
{
int i = index % 8;
v[index].x() = fSigns[i].x() * w2;
v[index].y() = fSigns[i].y() * h2;
v[index].z() = fSigns[i].z() * d2;
}
for( int iface = 0; iface < 6; iface ++)
{
n[iface] = -fNorms[iface];
#if defined(FLIP_D3D_NORMALS) && defined(CH_USE_D3D)
n[iface] = -n[iface];
#endif
face_data[ifd++] = 4;
int istep = (iface / 2) * vertStep; // which group of vertices, if texturing
for( int j = 0; j < 4; j++ )
{
int index = indices[iface][j];
face_data[ifd++] = index + istep;
face_data[ifd++] = iface;
}
}
face_data[ifd] = 0; // terminate array
#if 0 // || TRY_TO_FIX_POINT_LIGHTS
GxTransform3Wf transform = GetTransform();
(*(transform.GetMatrix()))[3][0] = 0;
(*(transform.GetMatrix()))[3][1] = 0;
(*(transform.GetMatrix()))[3][2] = 0;
for(int ifn = 0; ifn < 6; ifn++)
{
float w;
GxVec3f normT;
normT = transform.TransformW(n[ifn], w);
float mag = normT.magnitude();
if (w != 0.0) mag /= w;
if (mag != 0.0) n[ifn] *= 1. / (mag);
}
#endif
// Load the verts and faces
ChNrFaceArray facesAdded;
int numFacesAdded;
ChNrMeshAddFaces(mesh,
numVerts,
(ChNrVector*) v,
6,
(ChNrVector*) n,
face_data,
&numFacesAdded,
&facesAdded);
#if defined(CH_USE_D3D)
numFacesAdded = facesAdded->GetSize();
#endif
#if 0 && defined(CH_USE_D3D)
DWORD dwVerts, dwNormals, dwFaceSize;
D3DVECTOR tmpV[24], tmpN[24];
mesh->GetVertices(&dwVerts, tmpV, &dwNormals, tmpN, &dwFaceSize, 0);
#endif
ChNrFace elt;
// Set the material for the whole mesh
for( iface = 0; iface < 6; iface ++)
{
GetElement(facesAdded, unsigned(iface), elt);
if(boolUseTexture)
SetTextureCoordinates(pTxMap, mesh, elt, iface);
materialMap.Set(mesh, elt);
#if 0 && defined(CH_USE_D3D)
D3DVECTOR Normal;
elt->GetNormal(&Normal);
//elt->SetNormal((ChNrVector*)(n+iface));
#endif
D3DRelease(elt);
}
if(boolUseTexture)
{
ChTextureHandle hdl = pTextureData->GetTextureHandle();
if(hdl)
{
// Texture guy got here first, apply it
//ChNrMeshSetTexture(mesh, hdl);
SetTexture(pTextureData);
}
}
ChNrFree(facesAdded);
delete [] v;
delete [] n;
delete [] face_data;
delete pTxMap;
pIterator->DidAShape();
pRC->UnlockScene();
pRC->UnlockQv(); // Unlock tree
}
#endif
return true;
}
bool ChQvCubeInstance::Draw(ChRenderContext *pRC, ChDrawIterator *pIterator)
{
#if defined( CH_USE_3DR )
{
Fixed32_t On = 1;
Fixed32_t Off = 0;
static long indices[6][4] =
{
{0, 1, 5, 4}, // front
{2, 3, 7, 6}, // back
{3, 0, 4, 7}, // left
{1, 2, 6, 5}, // right
{3, 2, 1, 0}, // top
{4, 5, 6, 7} // bottom
};
static PointF_t fSigns[8] =
{
{-1, 1, 1}, // top front left
{ 1, 1, 1}, // top right
{ 1, 1, -1}, // top right back
{-1, 1, -1}, // top left back
{-1, -1, 1}, // bottom left
{ 1, -1, 1}, // bottom right
{ 1, -1, -1}, // bottom right back
{-1, -1, -1} // bottom left back
};
static PointF_t fNorms[6] =
{ // indexed by face
{ 0, 0, 1},//
{ 0, 0, -1}, //
{-1, 0, 0}, //
{ 1, 0, 0}, //
{ 0, 1, 0}, //
{ 0, -1, 0} // bottom
};
G3dHandle_t hGC = pRC->GetGC();
Dword_t hRC = pRC->GetRC();
QvCube *pNode = (QvCube *)GetNode();
pRC->SetModelTransform(GetTransform());
pRC->SetShading(this);
Float_t cull = 1; // always backcull cubes
Fixed32_t wMattNum = 0; // always use material 0
G3dSetMatt( hGC, wMattNum, G3DM_BACK_CULL, (Float_t *)&cull );
// Make a material mapping; we will use later for each face
ChQvCubeMaterials materialMap( this );
/* Do the texture stuff - find it, make the map, set up 3dr for it, */
int boolUseTexture = SetupTexture(pRC);
ChQvCubeTextures *pTxMap = 0;
if(boolUseTexture)
{
pTxMap = new ChQvCubeTextures( this );
}
float h2 = pNode->height.value / 2.;
float w2 = pNode->width.value / 2.;
float d2 = pNode->depth.value / 2.;
Fixed32_t lCCW = true;
G3dGetState( hGC, G3DL_FRONT_CCW, &lCCW);
G3dSetState( hGC, G3DL_FRONT_CCW, &Off);
for( int face = 0; face < 6; face ++)
{
bool boolPureEmissive;
materialMap.Set(hRC, hGC, face, &boolPureEmissive);
pRC->SetModulation( boolUseTexture, boolPureEmissive);
G3dBeginPrim(hGC, G3D_PRM_POLYGON, 4);
PointF_t n, v;
n = fNorms[face];
for( int j = 0; j < 4; j++ )
{
int index = indices[face][j];
v.x = fSigns[index].x * w2;
v.y = fSigns[index].y * h2;
v.z = fSigns[index].z * d2;
if(boolUseTexture)
{
PointF_t textCoord = pTxMap->GetCoord3(face, j);
G3dAddPrimVtxF(hGC, &v, &n, &textCoord, 0);
}
else
{
G3dAddPrimVtxF(hGC, &v, &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))
#else
#endif //defined( CH_USE_3DR ) or others
return true;
}
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
void ChQvCubeInstance::SetTextureCoordinates(ChQvCubeTextures *pTxMap, ChNrMesh mesh, ChNrFace face, int faceNum)
{
int count = ChNrFaceGetVertexCount(face);
for(int j = 0; j < count; j++)
{
GxVec3f textCoord = pTxMap->GetCoord3(faceNum, j);
int index = ChNrFaceGetVertexIndex(face, j);
ChNrMeshSetTextureCoordinates(mesh, index, textCoord.x(), textCoord.y());
}
}
#endif
//////////////////////////////////////////////////////////////////////
ChQvCylinderInstance::ChQvCylinderInstance() : ChQvShapeInstance()
{
}
bool ChQvCylinderInstance::Construct(ChRenderContext *pRC, ChConstructionIterator *pIterator)
{
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
{
QvCylinder *pNode = (QvCylinder *)GetNode();
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->UnlockScene();
pRC->UnlockQv(); // Unlock tree
return 1;
}
m_boolConstructed = true;
ChNrMesh mesh = m_mesh = pRC->CreateMesh();
ChNrFrameAddVisual(GetFrame(), mesh);
D3DRelease(mesh);
ChNrObjectSetAppData(mesh, (unsigned long)this);
ChNrMeshSetColorSource(mesh,ColorFromFace); // alternative: ChNativeColorFromVertex
ChNrMeshSetPerspective(mesh,true);
ChNrMeshSetTextureTopology(mesh,true, false); // uwrap, vwrap
bool boolCull = (pNode->parts.value == QvCylinder::ALL); // if all sides are present, then cull
//boolCull = true;
int numFacets = CalcCylinderFacetCount(this, state);
// Make a material mapping; we will use later for each facet, top and bottom
ChQvCylinderMaterials materialMap( this );
pRC->AdjustTransparency(materialMap);
/* Do the texture stuff - make the map, assign to all the verts, */
ChQvCylinderTextures *pTxMap = new ChQvCylinderTextures( this, numFacets );
ChQvTextureRenderData *pTextureData = (ChQvTextureRenderData*)(GetTexture2()->GetRenderData());
bool boolUseTexture = !(pTextureData->IsEmpty()); // one -might- arrive
float h2 = pNode->height.value / 2.;
float r = pNode->radius.value;
float pi = atan(1.) * 4.;
float twoPi = pi * 2;
// Build the display list: verts, normals, and faces
int numFaces = numFacets + 2, numVerts = numFacets * 2, numNorms = numFacets + 2;
if (!boolCull) numNorms *= 2;
int vertStep = 0; // step to find verts for sides
if (boolUseTexture)
{
vertStep = numVerts;
numVerts *= 2;
}
// alloc face_data conservatively; might be a touch too big in some cases
int face_data_size = numFacets * 4 * 2 // for side faces
+ numFacets // side counts
+ 2 * numFacets * 2 // ends
+ 2 // end counts
+ 1; // terminator
if (!boolCull) face_data_size *= 2;
ChNrFaceData * face_data = new ChNrFaceData[face_data_size];
int ifd = 0; // index into face data
GxVec3f *n = new GxVec3f[numNorms];
GxVec3f *v = new GxVec3f[numVerts];
int normStep = numNorms / 2;
// We store both inside and outside normals if not backculled,
// but only store outsides if this is solid (not backCulled).
// We store all outside norms, first side norms, then ends,
// then same for insides if needed.
for( int facet = 0; facet < numFacets; facet ++)
{
float theta = facet * twoPi / numFacets;
float sintheta = sin(theta);
float costheta = cos(theta);
n[facet].x() = -sintheta;
n[facet].y() = 0;
n[facet].z() = -costheta;
if(!boolCull)
{
n[facet+normStep] = -n[facet]; // inside normal
}
v[facet*2].x() = -sintheta * r;
v[facet*2].y() = h2;
v[facet*2].z() = -costheta * r;
v[facet*2+1] = v[facet*2];
v[facet*2+1].y() = -h2;
}
n[facet].set(0,1,0);
if(!boolCull) n[facet+normStep] = -n[facet]; // inside normal
facet++;
n[facet].set(0,-1,0);
if(!boolCull) n[facet+normStep] = -n[facet]; // inside normal
facet++;
// Dupe the verts, to use for sides, if we have texture
if(boolUseTexture)
{
for( int i = 0; i < numVerts / 2; i ++)
{
v[i+vertStep] = v[i];
}
}
// Do the top
if(pNode->parts.value & QvCylinder::TOP)
{
face_data[ifd++] = numFacets; // count
for( int j = 0; j < numFacets; j ++)
{
// Use the even numbered vertices, in reversed order
int index = ((numFacets - j) * 2) % (numFacets * 2);
face_data[ifd++] = index; // vertex
face_data[ifd++] = numFacets; // normal
}
if(!boolCull)
{
// Back face - uses inside normal
face_data[ifd++] = numFacets; // count for this face
for( int j = 0; j < numFacets; j ++)
{
// Use the even numbered vertices, in reversed order from front face
int index = (j * 2) % (numFacets * 2);
face_data[ifd++] = index; // vertex
face_data[ifd++] = numFacets + normStep; // normal
}
}
}
// Do the bottom
if(pNode->parts.value & QvCylinder::BOTTOM)
{
// TODO : Make sure this order is right when we do textures
face_data[ifd++] = numFacets; // count for this face
for( int j = 0; j < numFacets; j ++)
{
// Use the odd numbered vertices, in mangled order
int index = ((j * 2) % (numFacets * 2)) + 1;
face_data[ifd++] = index; // vertex
face_data[ifd++] = (numFacets + 1); // normal
}
if(!boolCull)
{
// Back face - uses inside normal
face_data[ifd++] = numFacets; // count for this face
for( int j = 0; j < numFacets; j ++)
{
// Use the odd numbered vertices, in even more mangled order
int index = (numFacets * 2 - j * 2) % (numFacets * 2) + 1;
face_data[ifd++] = index; // vertex
face_data[ifd++] = (numFacets + 1) + normStep; // normal
}
}
}
// Do the sides
if(pNode->parts.value & QvCylinder::SIDES)
{
static int backPermute[4] = { 0, 1, 3, 2 };
static int permute[4] = { 0, 2, 3, 1 };
for( int facet = 0; facet < numFacets; facet ++)
{
face_data[ifd++] = 4; // count
for( int j = 0; j < 4; j++ )
{
int index = (facet * 2 + permute[j]) % (numFacets * 2);
face_data[ifd++] = index + vertStep;
face_data[ifd++] = (facet + (permute[j] / 2)) % numFacets;
}
}
if(!boolCull)
{
// Back face - uses inside normal
for( int facet = 0; facet < numFacets; facet ++)
{
face_data[ifd++] = 4; // count
for( int j = 0; j < 4; j++ )
{
int index = (facet * 2 + backPermute[j]) % (numFacets * 2);
face_data[ifd++] = index + vertStep;
face_data[ifd++] = ((facet + (permute[j] / 2)) % numFacets) + normStep;
}
}
}
}
face_data[ifd] = 0; // terminate array
// Load the verts and faces
ChNrFaceArray facesAdded;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -