WMetalMaterial::WMetalMaterial(string iName,unsigned int iID,WVector3 Fr,float iexp):WMaterial(MATERIAL_METAL,iName,iID,false,Fr),exp(iexp) { k=2.0f*(color/(WVector3(1)-color)).sqrtElement(); WVector3 colorSqrt=color.sqrtElement(); eta=(WVector3(1)+colorSqrt)/(WVector3(1)-colorSqrt); // k.showCoords(); // eta.showCoords(); }
void WPrimitive::buildBBox() { if(nVertices<1) return; WVector3 delta=WVector3(WBoundingBox::delta); box.pMin=WVector3(vertices[0],vertices[1],vertices[2])-delta; box.pMax=WVector3(vertices[0],vertices[1],vertices[2])+delta; for(unsigned int i=1;i<nVertices;i++) { box.merge( WVector3(vertices[3*i],vertices[3*i+1],vertices[3*i+2]) ); } return; }
void WPrimitive::buildSubP() { if(nFaces==0) return; nSubPs=(nFaces+nFacesPerSubP-1)/nFacesPerSubP; //cout<<nFaces<<' '<<nSubPs<<endl; //最后一个SubPrimitive包含的面数 unsigned int lastNFace=nFaces-nFacesPerSubP*(nSubPs-1); subPs=new WSubPrimitive[nSubPs]; int nthSubP=-1; WTriangle t; for(unsigned int i=0;i<nFaces;i++) { getTriangle(i,t);//获得第i个三角形 if(i%nFacesPerSubP==0)//获得下一个subp { WVector3 delta=WVector3(WBoundingBox::delta); nthSubP++; subPs[nthSubP].box.pMin=t.point1-delta; subPs[nthSubP].box.pMax=t.point1+delta; subPs[nthSubP].beginIndex=i; subPs[nthSubP].nFaces=nFacesPerSubP; subPs[nthSubP].pPrimitive=this; } subPs[nthSubP].box.merge(t); } subPs[nthSubP].nFaces=lastNFace; }
//叉乘 WVector3 WVector3::cross(const WVector3&i)const { return WVector3( y*i.z-z*i.y, z*i.x-x*i.z, x*i.y-y*i.x); }
bool WPrimitive::getTriangle(unsigned int nthFace,WTriangle&tri) { if(nthFace>=nFaces||nthFace<0) return false; float*p; //找到顶点位置 p=&vertices[vertexIndices[nthFace*3]*3]; tri.point1=WVector3(*p,*(p+1),*(p+2)); p=&vertices[vertexIndices[nthFace*3+1]*3]; tri.point2=WVector3(*p,*(p+1),*(p+2)); p=&vertices[vertexIndices[nthFace*3+2]*3]; tri.point3=WVector3(*p,*(p+1),*(p+2)); //找到法向量 p=&normals[normalIndices[nthFace*3]*3]; tri.normal1=WVector3(*p,*(p+1),*(p+2)); p=&normals[normalIndices[nthFace*3+1]*3]; tri.normal2=WVector3(*p,*(p+1),*(p+2)); p=&normals[normalIndices[nthFace*3+2]*3]; tri.normal3=WVector3(*p,*(p+1),*(p+2)); //找到贴图坐标 p=&texcoords[texCoordIndices[nthFace*3]*2]; tri.texCoord1=WVector2(*p,*(p+1)); p=&texcoords[texCoordIndices[nthFace*3+1]*2]; tri.texCoord2=WVector2(*p,*(p+1)); p=&texcoords[texCoordIndices[nthFace*3+2]*2]; tri.texCoord3=WVector2(*p,*(p+1)); tri.mtlId=mtlIndices[nthFace]; return true; }
void WRandomCamera::setColor( float R,float G,float B, WVector3 idir ) { //nDir为屏幕中心到idir在屏幕上的中心投影点的向量 WVector3 nDir = idir / (idir.dot(this->dir)) - dir; float xRatio = nDir.dot(this->x) / x.lengthSquared(); float yRatio = nDir.dot(this->y) / y.lengthSquared(); unsigned int xPos = (xRatio + 1.0f) / 2.0f * this->resolutionX; unsigned int yPos = (yRatio + 1.0f) / 2.0f * this->resolutionY; if(xPos>=resolutionX || yPos>=resolutionY) return; unsigned int* currSamplePtr = &(this->nSamples[xPos + resolutionX * yPos]); WVector3 currColor = film.getColor(xPos, yPos) * (*currSamplePtr); currColor = (currColor + WVector3(R, G, B)) / (float)(++(*currSamplePtr)); // cout<<*currSamplePtr<<endl; // printf("the position in screen is %d %d \n",xPos,yPos); film.setColor(xPos, yPos, currColor.x, currColor.y, currColor.z); }
void WMetalMaterial::refreshColor() { k=2.0f*(color/(WVector3(1)-color)).sqrtElement(); WVector3 colorSqrt=color.sqrtElement(); eta=(WVector3(1)+colorSqrt)/(WVector3(1)-colorSqrt); }
WVector3 operator/(float n,const WVector3&i) { return WVector3(n/i.x,n/i.y,n/i.z); }
WVector3 WVector3::sqrtElement()const { return WVector3(sqrt(x),sqrt(y),sqrt(z)); }
//数除 WVector3 operator/(const WVector3&i,float n) { return WVector3(i.x/n,i.y/n,i.z/n); }
WVector3 operator*(const WVector3&i1,const WVector3&i2) { // cout<<1<<endl; return WVector3(i1.x*i2.x,i1.y*i2.y,i1.z*i2.z); }
WVector3 operator*(float n,const WVector3&i) { return WVector3(i.x*n,i.y*n,i.z*n); }
//数乘 WVector3 operator*(const WVector3&i,float n) { return WVector3(i.x*n,i.y*n,i.z*n); }
//减法 WVector3 WVector3::operator -(const WVector3&i)const { return WVector3(x-i.x,y-i.y,z-i.z); }
//加法 WVector3 WVector3::operator +(const WVector3&i)const { return WVector3(x+i.x,y+i.y,z+i.z); }
bool WUtil::RayIntersectCube(float cubeHalfSize, WVector3 rayPos, WVector3 rayDir, WVector3 cubePos) { //if the ray position is inside the box, it intersects then if (fabs(rayPos.x) < cubeHalfSize && fabs(rayPos.y) < cubeHalfSize && fabs(rayPos.z) < cubeHalfSize) return true; //allocate 24 vertices for the cube WVector3 verts[24]; //fill the vertex buffer data verts[0] = WVector3(-0.5f, -0.5f, -0.5f); verts[1] = WVector3(-0.5f, 0.5f, -0.5f); verts[2] = WVector3(0.5f, 0.5f, -0.5f); verts[3] = WVector3(0.5f, -0.5f, -0.5f); verts[4] = WVector3(-0.5f, -0.5f, 0.5f); verts[5] = WVector3(0.5f, -0.5f, 0.5f); verts[6] = WVector3(0.5f, 0.5f, 0.5f); verts[7] = WVector3(-0.5f, 0.5f, 0.5f); verts[8] = WVector3(-0.5f, 0.5f, -0.5f); verts[9] = WVector3(-0.5f, 0.5f, 0.5f); verts[10] = WVector3(0.5f, 0.5f, 0.5f); verts[11] = WVector3(0.5f, 0.5f, -0.5f); verts[12] = WVector3(-0.5f, -0.5f, -0.5f); verts[13] = WVector3(0.5f, -0.5f, -0.5f); verts[14] = WVector3(0.5f, -0.5f, 0.5f); verts[15] = WVector3(-0.5f, -0.5f, 0.5f); verts[16] = WVector3(-0.5f, -0.5f, 0.5f); verts[17] = WVector3(-0.5f, 0.5f, 0.5f); verts[18] = WVector3(-0.5f, 0.5f, -0.5f); verts[19] = WVector3(-0.5f, -0.5f, -0.5f); verts[20] = WVector3(0.5f, -0.5f, -0.5f); verts[21] = WVector3(0.5f, 0.5f, -0.5f); verts[22] = WVector3(0.5f, 0.5f, 0.5f); verts[23] = WVector3(0.5f, -0.5f, 0.5f); //scale the vertices for (int i = 0; i < 24; i++) { verts[i] *= cubeHalfSize * 2; verts[i] += cubePos; } //allocate 36 unsigned ints for the indices of the cube unsigned int _indices[36]; //fill cube's index data _indices[0] = 0; _indices[1] = 1; _indices[2] = 2; _indices[3] = 0; _indices[4] = 2; _indices[5] = 3; _indices[6] = 4; _indices[7] = 5; _indices[8] = 6; _indices[9] = 4; _indices[10] = 6; _indices[11] = 7; _indices[12] = 8; _indices[13] = 9; _indices[14] = 10; _indices[15] = 8; _indices[16] = 10; _indices[17] = 11; _indices[18] = 12; _indices[19] = 13; _indices[20] = 14; _indices[21] = 12; _indices[22] = 14; _indices[23] = 15; _indices[24] = 16; _indices[25] = 17; _indices[26] = 18; _indices[27] = 16; _indices[28] = 18; _indices[29] = 19; _indices[30] = 20; _indices[31] = 21; _indices[32] = 22; _indices[33] = 20; _indices[34] = 22; _indices[35] = 23; for (unsigned int i = 0; i < 12; i++) { WVector3 v0 = verts[_indices[i * 3 + 0]]; WVector3 v1 = verts[_indices[i * 3 + 1]]; WVector3 v2 = verts[_indices[i * 3 + 2]]; WVector3 e1, e2, h, s, q; float a, f, u, v; e1 = v1 - v0; //vector ( e1, v1, v0 ); e2 = v2 - v0; //vector ( e2, v2, v0 ); h = WVec3Cross(rayDir, e2); a = WVec3Dot(e1, h); if (a > -0.00001 && a < 0.00001) continue; //no intersection f = 1 / a; s = rayPos - v0; //vector ( s, p, v0 ); u = f * (WVec3Dot(s, h)); if (u < 0.0 || u > 1.0) continue; //no intersection q = WVec3Cross(s, e1); v = f * WVec3Dot(rayDir, q); if (v < 0.0 || u + v > 1.0) continue; //no intersection // at this stage we can compute t to find out where // the intersection point is on the line float t = f * WVec3Dot(e2, q); if (t > 0.00001) // ray intersection return true; } return false; }
WVector3 operator/(const WVector3&i,const WVector3&n) { return WVector3(i.x/n.x,i.y/n.y,i.z/n.z); }