#ifndef CHESS_H #define CHESS_H #include "Object3D.h" #include "GeoAlgs.h" class ChessBoard : public ObjectComposite { public: ChessBoard(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, real dx, real dy, real dz, Material* white, Material* black) :ObjectComposite(center, xe, ye, ze) { real currX = 0; real currY = 0; real currZ = center.getZ(); Vector3DW squareOrigin; squareOrigin.setZ(currZ); int index; Material* maux; quickCheck_ = new Paralelepipedo(center, xe, ye, ze, dx*(real)8, dy*(real)8, dz, white); for(int i=0; i<8; i++) for(int j=0; j<8; j++) { index = i+8*j; currX = center.getX() + ((real)i - (real)3.5) * (real)2 * dx; currY = center.getY() + ((real)j - (real)3.5) * (real)2 * dy; squareOrigin.setX(currX); squareOrigin.setY(currY); if((i+j) & 0x00000001) maux = white; else maux = black; components_.push_back(new Paralelepipedo(squareOrigin, xe, ye, ze, dx, dy, dz, maux)); // squares_[index] = new Paralelepipedo(squareOrigin, xe, ye, ze, dx, dy, dz, maux); } }; ~ChessBoard() { delete(quickCheck_); }; virtual bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { // if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; if(!quickCheck_->rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: // Paralelepipedo* squares_[64]; Paralelepipedo* quickCheck_; }; class Base2 : public FunctionRevolution { public: Base2(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, real minRadius, real maxRadius, real height, Material* material) :FunctionRevolution(center, xe, ye, ze, material) { ti_ = 0; tf_ = height; xMult_ = ((real)7 * M_PI) / ((real)4 * height); sinMult_ = (maxRadius - minRadius) / (real)2; sinAdd_ = (maxRadius + minRadius) / (real)2; maxRadius_ = maxRadius; }; real f(real x) { return sin(x*xMult_ + (real)(M_PI / 4.0))*sinMult_ + sinAdd_; }; real dfdt(real x) { return cos(x*xMult_ + (real)(M_PI / 4.0))*sinMult_*xMult_; }; protected: real xMult_; real sinMult_; real sinAdd_; }; class Base3 : public FunctionRevolution { public: Base3(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, real maxRadius, real minRadius, real height, Material* material) :FunctionRevolution(center, xe, ye, ze, material) { ti_ = 0; tf_ = height; xMult_ = (real)4.0 / height; powAdd_ = maxRadius; powMult_ = (maxRadius - minRadius) / (real)2.0; maxRadius_ = maxRadius; }; real f(real x) { return powAdd_ - pow(x * xMult_, 0.5) * powMult_; }; real dfdt(real x) { return (real)-0.5 * (real)pow(x * xMult_, -0.5) * powMult_ * xMult_; }; protected: real powAdd_; real powMult_; real xMult_; }; class Base4 : public FunctionRevolution { public: Base4(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, real maxRadius, real minRadius, real height, Material* material) :FunctionRevolution(center, xe, ye, ze, material) { ti_ = 0; tf_ = height; xMult_ = (real)6.0 / height; powAdd_ = minRadius; powMult_ = (maxRadius - minRadius) / (real)9.0; maxRadius_ = maxRadius; }; real f(real x) { return (- pow(x * xMult_ - (real)3, 2.0) + (real)9.0) * powMult_ + powAdd_; }; real dfdt(real x) { return - (real)2.0 * (x * xMult_ - (real)3) * xMult_ * powMult_; }; protected: real powAdd_; real powMult_; real xMult_; }; class Cone : public FunctionRevolution { public: Cone(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, real initRadius, real finRadius, real height, Material* material) :FunctionRevolution(center, xe, ye, ze, material) { ti_ = 0; tf_ = height; a_ = (initRadius - finRadius) / height; b_ = initRadius; if(initRadius > finRadius) maxRadius_ = initRadius; else maxRadius_ = finRadius; }; real f(real x) { return - a_ * x + b_; }; real dfdt(real x) { return - a_; }; protected: real a_; real b_; }; class PieceBase : public ObjectComposite { public: PieceBase(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, real radius, real baseHeight, real sinHeight, real rootHeight, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; components_.push_back(new Circle(vaux, xe, ye, ze, radius, material)); components_.push_back(new Cylinder(vaux, xe, ye, ze, radius, baseHeight, material)); vaux = vaux + (ze * baseHeight); components_.push_back(new Circle(vaux, xe, ye, ze, radius, material)); components_.push_back(new Base2(vaux, xe, ye, ze, radius*(real)0.75, radius, sinHeight, material)); vaux = vaux + (ze * sinHeight); components_.push_back(new Circle(vaux, xe, ye, ze, radius*(real)0.85, material)); components_.push_back(new Base3(vaux, xe, ye, ze, radius*(real)0.85, radius*(real)0.25, rootHeight, material)); }; protected: Material* material_; }; class Pawn : public ObjectComposite { public: Pawn(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; components_.push_back(new PieceBase(vaux, xe, ye, ze, (real)1.6, (real)0.5, (real)1, (real)2.5, material)); vaux = vaux + (ze * (real)4.7); components_.push_back(new Sphere(vaux, xe, ye, ze, (real)0.9, material)); maxRadius_ = (real)1.8; maxHeight_ = (real)6.0; }; bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { Vector3DW rOrigin1 = T * (rOrigin - center_); Vector3DW rDirection1 = T * rDirection; if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: Material* material_; real maxRadius_; real maxHeight_; }; class Knight : public ObjectComposite { public: Knight(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; real radius = (real)1.8; real baseHeight = (real)0.5; real sinHeight = (real)1.0; components_.push_back(new Circle(vaux, xe, ye, ze, radius, material)); components_.push_back(new Cylinder(vaux, xe, ye, ze, radius, baseHeight, material)); vaux = vaux + (ze * baseHeight); components_.push_back(new Circle(vaux, xe, ye, ze, radius, material)); components_.push_back(new Base2(vaux, xe, ye, ze, radius*(real)0.75, radius, sinHeight, material)); vaux = vaux + (ze * sinHeight); components_.push_back(new Circle(vaux, xe, ye, ze, radius*(real)0.85, material)); vaux = vaux + (ze * (real)2.0); components_.push_back(new Paralelepipedo(vaux, xe, ye, ze, (real)0.5, (real)1.0, (real)2.5, material)); Vector3DW vaux2 = vaux; vaux2 = vaux2 + (ze * (real)1.8); vaux2 = vaux2 + (ye * (real)0.5); vaux2 = vaux2 + (xe * (real)0.5); components_.push_back(new Sphere(vaux2, xe, ye, ze, (real)0.3, material)); vaux2 = vaux2 - (xe * (real)1.0); components_.push_back(new Sphere(vaux2, xe, ye, ze, (real)0.3, material)); vaux = vaux + (ze * (real)1.3); vaux = vaux + (ye * (real)0.7); real ang = (real)(M_PI / 6.0); Vector3DW nxe = xe; Vector3DW nye = ye; Vector3DW nze = ze; nye.setY(nye.getY() * cos(ang) - nye.getZ() * sin(ang)); nye.setZ(nye.getY() * sin(ang) + nye.getZ() * cos(ang)); nze.setY(nze.getY() * cos(ang) - nze.getZ() * sin(ang)); nze.setZ(nze.getY() * sin(ang) + nze.getZ() * cos(ang)); components_.push_back(new Paralelepipedo(vaux, nxe, nye, nze, (real)0.5, (real)1.8, (real)0.6, material)); maxRadius_ = (real)2.5; maxHeight_ = (real)6.5; }; bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { Vector3DW rOrigin1 = T * (rOrigin - center_); Vector3DW rDirection1 = T * rDirection; if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: Material* material_; real maxRadius_; real maxHeight_; }; class Bishop : public ObjectComposite { public: Bishop(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; components_.push_back(new PieceBase(vaux, xe, ye, ze, (real)1.8, (real)0.5, (real)1, (real)3.0, material)); vaux = vaux + (ze * (real)4.5); components_.push_back(new Base4(vaux, xe, ye, ze, (real)1.2, (real)0.75, (real)0.5, material)); vaux = vaux + (ze * (real)0.5); components_.push_back(new Base4(vaux, xe, ye, ze, (real)1.1, (real)0.75, (real)1.3, material)); vaux = vaux + (ze * (real)1.3); components_.push_back(new Cone(vaux, xe, ye, ze, (real)0.75, (real)0.0, (real)0.65, material)); maxRadius_ = (real)1.8; maxHeight_ = (real)7.0; }; bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { Vector3DW rOrigin1 = T * (rOrigin - center_); Vector3DW rDirection1 = T * rDirection; if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: Material* material_; real maxRadius_; real maxHeight_; }; class Rook : public ObjectComposite { public: Rook(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; real baseRadius = (real)1.8; real towerRadius = (real)1.2; real blockSize = (real)0.3; components_.push_back(new PieceBase(vaux, xe, ye, ze, baseRadius, (real)0.5, (real)1, (real)3.5, material)); vaux = vaux + (ze * (real)5.0); components_.push_back(new Circle(vaux, xe, ye, ze, towerRadius, material)); components_.push_back(new Cylinder(vaux, xe, ye, ze, towerRadius, (real)1.0, material)); vaux = vaux + (ze * (real)1.0); components_.push_back(new Circle(vaux, xe, ye, ze, towerRadius, material)); vaux = vaux + (ze * (blockSize / (real)2)); Vector3DW vaux2; vaux2 = vaux + (xe * (towerRadius - blockSize)); components_.push_back(new Paralelepipedo(vaux2, xe, ye, ze, blockSize, blockSize, blockSize/(real)2, material)); vaux2 = vaux - (xe * (towerRadius - blockSize)); components_.push_back(new Paralelepipedo(vaux2, xe, ye, ze, blockSize, blockSize, blockSize/(real)2, material)); vaux2 = vaux + (ye * (towerRadius - blockSize)); components_.push_back(new Paralelepipedo(vaux2, xe, ye, ze, blockSize, blockSize, blockSize/(real)2, material)); vaux2 = vaux - (ye * (towerRadius - blockSize)); components_.push_back(new Paralelepipedo(vaux2, xe, ye, ze, blockSize, blockSize, blockSize/(real)2, material)); maxRadius_ = (real)1.8; maxHeight_ = (real)6.5; }; bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { Vector3DW rOrigin1 = T * (rOrigin - center_); Vector3DW rDirection1 = T * rDirection; if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: Material* material_; real maxRadius_; real maxHeight_; }; class Queen : public ObjectComposite { public: Queen(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; components_.push_back(new PieceBase(vaux, xe, ye, ze, (real)1.8, (real)0.5, (real)1, (real)4.0, material)); vaux = vaux + (ze * (real)5.5); components_.push_back(new Base4(vaux, xe, ye, ze, (real)0.9, (real)0.7, (real)0.3, material)); vaux = vaux + (ze * (real)0.3); components_.push_back(new Cone(vaux, xe, ye, ze, (real)0.7, (real)0.9, (real)1.0, material)); vaux = vaux + (ze * (real)0.5); components_.push_back(new Base4(vaux, xe, ye, ze, (real)0.9, (real)0.0, (real)1.0, material)); vaux = vaux + (ze * (real)1.0); components_.push_back(new Sphere(vaux, xe, ye, ze, (real)0.3, material)); maxRadius_ = (real)1.8; maxHeight_ = (real)8.0; }; bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { Vector3DW rOrigin1 = T * (rOrigin - center_); Vector3DW rDirection1 = T * rDirection; if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: Material* material_; real maxRadius_; real maxHeight_; }; class King : public ObjectComposite { public: King(Vector3DW& center, Vector3DW& xe, Vector3DW& ye, Vector3DW& ze, Material* material) :ObjectComposite(center, xe, ye, ze) { material_ = material; Vector3DW vaux = center; components_.push_back(new PieceBase(vaux, xe, ye, ze, (real)1.8, (real)0.5, (real)1, (real)4.0, material)); vaux = vaux + (ze * (real)5.5); components_.push_back(new Base4(vaux, xe, ye, ze, (real)1.0, (real)0.8, (real)0.3, material)); vaux = vaux + (ze * (real)0.3); components_.push_back(new Cone(vaux, xe, ye, ze, (real)0.8, (real)1.0, (real)1.0, material)); vaux = vaux + (ze * (real)0.5); components_.push_back(new Base4(vaux, xe, ye, ze, (real)1.0, (real)0.0, (real)1.0, material)); vaux = vaux + (ze * (real)1.0); components_.push_back(new Paralelepipedo(vaux, xe, ye, ze, (real)0.3, (real)0.3, (real)0.9, material)); vaux = vaux + (ze * (real)0.4); components_.push_back(new Paralelepipedo(vaux, xe, ye, ze, (real)0.3, (real)0.6, (real)0.2, material)); maxRadius_ = (real)1.8; maxHeight_ = (real)8.5; }; bool rayIntersect( Vector3DW& rOrigin, Vector3DW& rDirection, Vector3DW& intersectionPoint, Vector3DW& intersectionNormal, real& intersectionDistance, Color& color, real& ka, real& kd, real& ks) { Vector3DW rOrigin1 = T * (rOrigin - center_); Vector3DW rDirection1 = T * rDirection; if(!cylinderIntersection2(maxRadius_, maxHeight_, rOrigin1, rDirection1)) return false; return ObjectComposite::rayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color, ka, kd, ks); }; protected: Material* material_; real maxRadius_; real maxHeight_; }; #endif