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:
0077: CTriangle::CTriangle()
0078: {
0079: }
0080:
0081: void CTriangle::Init(OBJ_DATA *pData)
0082: {
0083: ((CPrimitive*)this)->Init(pData);
0084:
0085: this->pos[0] = D3DXVECTOR4( pData->triangle.x0[0],
0086: pData->triangle.x0[1],
0087: pData->triangle.x0[2],
0088: 1.0f);
0089: this->pos[1] = D3DXVECTOR4( pData->triangle.x1[0],
0090: pData->triangle.x1[1],
0091: pData->triangle.x1[2],
0092: 1.0f);
0093: this->pos[2] = D3DXVECTOR4( pData->triangle.x2[0],
0094: pData->triangle.x2[1],
0095: pData->triangle.x2[2],
0096: 1.0f);
0097:
0098:
0099: D3DXVECTOR4 t0 = this->pos[1]-this->pos[0];
0100: D3DXVECTOR4 t1 = this->pos[2]-this->pos[0];
0101: D3DXVec3Cross((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&t1, (D3DXVECTOR3*)&t0);
0102: D3DXVec3Normalize((D3DXVECTOR3*)&normal, (D3DXVECTOR3*)&normal);
0103: normal.w = 0;
0104: }
0105:
0106: float CTriangle::IsAcross(D3DXVECTOR4 *n, D3DXVECTOR4 *p, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0107: {
0108: FLOAT t;
0109:
0110:
0111: D3DXVECTOR4 xp = this->pos[0]-(*x);
0112:
0113: FLOAT xpn = D3DXVec3Dot((D3DXVECTOR3 *)&xp, (D3DXVECTOR3 *)&normal);
0114: FLOAT vn = D3DXVec3Dot((D3DXVECTOR3 *)v, (D3DXVECTOR3 *)&normal);
0115:
0116: if(-0.00001f<=vn)return -INFINTY_DIST;
0117:
0118: t = xpn/vn;
0119:
0120: if(t<0) return -INFINTY_DIST;
0121:
0122: *p = (*x)+t*(*v);
0123: *n = normal;
0124:
0125: D3DXVECTOR4 d0, d1;
0126: D3DXVECTOR3 c;
0127: d0 = (*p)-this->pos[0];
0128: d1 = this->pos[1]-this->pos[0];
0129: D3DXVec3Cross(&c, (D3DXVECTOR3*)&d1, (D3DXVECTOR3*)&d0);
0130: if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)>0)return -INFINTY_DIST;
0131: d0 = (*p)-this->pos[1];
0132: d1 = this->pos[2]-this->pos[1];
0133: D3DXVec3Cross(&c, (D3DXVECTOR3*)&d1, (D3DXVECTOR3*)&d0);
0134: if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)>0)return -INFINTY_DIST;
0135: d0 = (*p)-this->pos[2];
0136: d1 = this->pos[0]-this->pos[2];
0137: D3DXVec3Cross(&c, (D3DXVECTOR3*)&d1, (D3DXVECTOR3*)&d0);
0138: if(D3DXVec3Dot(&c, (D3DXVECTOR3 *)&normal)>0)return -INFINTY_DIST;
0139:
0140: return t;
0141: }
0142:
0143:
0144:
0145:
0146:
0147:
0148:
0149:
0150:
0151: CMesh::CMesh()
0152: {
0153: m_num = 0;
0154: m_ppPrim = NULL;
0155: }
0156:
0157: CMesh::~CMesh()
0158: {
0159: Delete();
0160: }
0161:
0162: void CMesh::Init(OBJ_DATA *pData, int num)
0163: {
0164: this->m_num = num;
0165:
0166: m_ppPrim = new CPrimitive*[num];
0167:
0168: for(int i=0;i<num;i++){
0169: switch(pData[i].type){
0170: case OBJ_TYPE_SPHERE:
0171: m_ppPrim[i] = new CSphere();
0172: ((CSphere*)m_ppPrim[i])->Init(pData+i);
0173: break;
0174: case OBJ_TYPE_TRIANGLE:
0175: m_ppPrim[i] = new CTriangle();
0176: ((CTriangle*)m_ppPrim[i])->Init(pData+i);
0177: break;
0178: }
0179: }
0180: }
0181:
0182: void CMesh::Delete()
0183: {
0184: int i;
0185:
0186: if(m_ppPrim){
0187: for(i=0;i<m_num;i++){
0188: if(m_ppPrim[i]) {delete m_ppPrim[i];m_ppPrim[i]=NULL;}
0189: }
0190: delete[] m_ppPrim;
0191: m_ppPrim = NULL;
0192: }
0193: m_num = 0;
0194: }
0195:
0196: float CMesh::IsAcross(float dist, D3DXVECTOR4 *n, D3DXVECTOR4 *p, CPrimitive **dest, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0197: {
0198: float ttmp;
0199: D3DXVECTOR4 ntmp, ptmp;
0200:
0201: for(int i = 0; i<m_num; i++){
0202: switch(m_ppPrim[i]->m_type){
0203: case OBJ_TYPE_SPHERE:
0204: ttmp = ((CSphere*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0205: break;
0206: case OBJ_TYPE_TRIANGLE:
0207: ttmp = ((CTriangle*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0208: break;
0209: }
0210: if(0<=ttmp && ttmp<dist){
0211: dist = ttmp;
0212: *n = ntmp;
0213: *p = ptmp;
0214: *dest = m_ppPrim[i];
0215: }
0216: }
0217:
0218: return dist;
0219: }
0220:
0221: bool CMesh::IsAcross(float dist, const D3DXVECTOR4 *x, const D3DXVECTOR4 *v)
0222: {
0223: D3DXVECTOR4 ntmp, ptmp;
0224:
0225: for(int i = 0; i<m_num; i++){
0226: float d;
0227: switch(m_ppPrim[i]->m_type){
0228: case OBJ_TYPE_SPHERE:
0229: d = ((CSphere*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0230: break;
0231: case OBJ_TYPE_TRIANGLE:
0232: d = ((CTriangle*)m_ppPrim[i])->IsAcross(&ntmp, &ptmp, x, v);
0233: break;
0234: }
0235: if(0.001*dist<=d && d<0.99f*dist) return TRUE;
0236: }
0237:
0238: return FALSE;
0239: }
0240:
0241:
0242: };
0243: