0001: #include "stdafx.h"
0002: #include "math.h"
0003: #include "prim.h"
0004:
0005: namespace Render {
0006:
0007:
0008:
0009:
0010: void CPrimitive::Init(OBJ_DATA *pData)
0011: {
0012: m_type=pData->type;
0013:
0014: this->m_material = pData->material;
0015: }
0016:
0017: D3DXVECTOR3 *CPrimitive::GetColor(D3DXVECTOR3 *dest, float LN, float HN )
0018: {
0019: *dest = *(D3DXVECTOR3*)&this->m_material.COLOR_AMB
0020: + *(D3DXVECTOR3*)&this->m_material.COLOR_DIF * LN
0021: + *(D3DXVECTOR3*)&this->m_material.COLOR_SPE * powf(HN, this->m_material.speq_power);
0022:
0023: return dest;
0024: }
0025:
0026:
0027:
0028: CSphere::CSphere()
0029: {
0030: }
0031:
0032: void CSphere::Init(OBJ_DATA *pData)
0033: {
0034: ((CPrimitive*)this)->Init(pData);
0035:
0036: this->center.x = pData->sphere.center[0];
0037: this->center.y = pData->sphere.center[1];
0038: this->center.z = pData->sphere.center[2];
0039:
0040: radius_sq = pData->sphere.radius;
0041: radius_sq *= radius_sq;
0042: }
0043:
0044: float CSphere::IsAcross(D3DXVECTOR4 *n, D3DXVECTOR4 *p, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0045: {
0046: FLOAT t, tp, tn;
0047:
0048:
0049:
0050: D3DXVECTOR4 xc = (*x)-center;
0051: FLOAT xc2 = D3DXVec3Dot((D3DXVECTOR3 *)&xc, (D3DXVECTOR3 *)&xc);
0052: FLOAT vxc = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&xc);
0053: FLOAT D = sqrtf(vxc*vxc-xc2+radius_sq);
0054:
0055: if(D<0) return -INFINTY_DIST;
0056:
0057: tp = -vxc+D;
0058: tn = -vxc-D;
0059:
0060: if(tn<0){
0061: if(tp<0) return -INFINTY_DIST;
0062: t = tp;
0063: }else{
0064: t = tn;
0065: }
0066:
0067: *p = (*x)+t*(*v);
0068: *n = *p-center;
0069: D3DXVec3Normalize((D3DXVECTOR3*)n, (D3DXVECTOR3*)n);
0070:
0071: return t;
0072: }
0073:
0074:
0075:
0076: CTriangle::CTriangle()
0077: {
0078: }
0079:
0080: void CTriangle::Init(OBJ_DATA *pData)
0081: {
0082: ((CPrimitive*)this)->Init(pData);
0083:
0084: this->pos[0] = D3DXVECTOR4( pData->triangle.x0[0],
0085: pData->triangle.x0[1],
0086: pData->triangle.x0[2],
0087: 1.0f);
0088: this->pos[1] = D3DXVECTOR4( pData->triangle.x1[0],
0089: pData->triangle.x1[1],
0090: pData->triangle.x1[2],
0091: 1.0f);
0092: this->pos[2] = D3DXVECTOR4( pData->triangle.x2[0],
0093: pData->triangle.x2[1],
0094: pData->triangle.x2[2],
0095: 1.0f);
0096:
0097:
0098: D3DXVECTOR4 t0 = this->pos[1]-this->pos[0];
0099: D3DXVECTOR4 t1 = this->pos[2]-this->pos[0];
0100: D3DXVec3Cross((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&t1, (D3DXVECTOR3*)&t0);
0101: D3DXVec3Normalize((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&normal);
0102: normal.w = 0;
0103: }
0104:
0105: float CTriangle::IsAcross(D3DXVECTOR4 *n, D3DXVECTOR4 *p, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0106: {
0107: FLOAT t;
0108:
0109:
0110: D3DXVECTOR4 xp = this->pos[0]-(*x);
0111:
0112: FLOAT xpn = D3DXVec3Dot((D3DXVECTOR3 *)&xp, (D3DXVECTOR3 *)&normal);
0113: FLOAT vn = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&normal);
0114:
0115: if(-0.0000001f<=vn)return -INFINTY_DIST;
0116:
0117: t = xpn/vn;
0118:
0119: if(t<0) return -INFINTY_DIST;
0120:
0121: *p = (*x)+t*(*v);
0122: *n = normal;
0123:
0124: D3DXVECTOR4 d0, d1;
0125: D3DXVECTOR3 c;
0126: d0 = (*p)-this->pos[0];
0127: d1 = this->pos[1]-this->pos[0];
0128: D3DXVec3Cross(&c, (D3DXVECTOR3*)&d0, (D3DXVECTOR3*)&d1);
0129: if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)<0)return -INFINTY_DIST;
0130: d0 = (*p)-this->pos[1];
0131: d1 = this->pos[2]-this->pos[1];
0132: D3DXVec3Cross(&c, (D3DXVECTOR3*)&d0, (D3DXVECTOR3*)&d1);
0133: if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)<0)return -INFINTY_DIST;
0134: d0 = (*p)-this->pos[2];
0135: d1 = this->pos[0]-this->pos[2];
0136: D3DXVec3Cross(&c, (D3DXVECTOR3*)&d0, (D3DXVECTOR3*)&d1);
0137: if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)<0)return -INFINTY_DIST;
0138:
0139: return t;
0140: }
0141:
0142:
0143:
0144:
0145:
0146:
0147:
0148:
0149: CMesh::CMesh()
0150: {
0151: m_num = 0;
0152: m_ppPrim = NULL;
0153: }
0154:
0155: CMesh::~CMesh()
0156: {
0157: Delete();
0158: }
0159:
0160: void CMesh::Init(OBJ_DATA *pData, int num)
0161: {
0162: this->m_num = num;
0163:
0164: m_ppPrim = new CPrimitive*[num];
0165:
0166: for(int i=0;i<num;i++){
0167: switch(pData[i].type){
0168: case OBJ_TYPE_SPHERE:
0169: m_ppPrim[i] = new CSphere();
0170: ((CSphere*)m_ppPrim[i])->Init(pData+i);
0171: break;
0172: case OBJ_TYPE_TRIANGLE:
0173: m_ppPrim[i] = new CTriangle();
0174: ((CTriangle*)m_ppPrim[i])->Init(pData+i);
0175: break;
0176: }
0177: }
0178: }
0179:
0180: void CMesh::Delete()
0181: {
0182: int i;
0183:
0184: if(m_ppPrim){
0185: for(i=0;i<m_num;i++){
0186: if(m_ppPrim[i]) {delete m_ppPrim[i];m_ppPrim[i]=NULL;}
0187: }
0188: delete[] m_ppPrim;
0189: m_ppPrim = NULL;
0190: }
0191: m_num = 0;
0192: }
0193:
0194: float CMesh::IsAcross(float dist, D3DXVECTOR4 *n, D3DXVECTOR4 *p, CPrimitive **dest, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0195: {
0196: float ttmp;
0197: D3DXVECTOR4 ntmp, ptmp;
0198:
0199: for(int i = 0; i<m_num; i++){
0200: switch(m_ppPrim[i]->m_type){
0201: case OBJ_TYPE_SPHERE:
0202: ttmp = ((CSphere*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0203: break;
0204: case OBJ_TYPE_TRIANGLE:
0205: ttmp = ((CTriangle*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0206: break;
0207: }
0208: if(0<=ttmp && ttmp<dist){
0209: dist = ttmp;
0210: *n = ntmp;
0211: *p = ptmp;
0212: *dest = m_ppPrim[i];
0213: }
0214: }
0215:
0216: return dist;
0217: }
0218:
0219: bool CMesh::IsAcross(float dist, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0220: {
0221: D3DXVECTOR4 ntmp, ptmp;
0222:
0223: for(int i = 0; i<m_num; i++){
0224: float d;
0225: switch(m_ppPrim[i]->m_type){
0226: case OBJ_TYPE_SPHERE:
0227: d = ((CSphere*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0228: break;
0229: case OBJ_TYPE_TRIANGLE:
0230: d = ((CTriangle*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0231: break;
0232: }
0233: if(0.001*dist<=d && d<0.99f*dist) return TRUE;
0234: }
0235:
0236: return FALSE;
0237: }
0238:
0239:
0240: };
0241: