// Returns for a given cursor coordinate, the intersection points it has // when projected to the near and far clipping planes of the view frustum. // NOTE: inspired by http://stackoverflow.com/a/18247608 void calculateMouseRay(int x, int y, Vec3Df *nearPoint, Vec3Df *farPoint) { // Fetch transformation matrices GLdouble modelview[16]; //world coordinates -> eye coordinates GLdouble projection[16]; //eye coordinates -> clip coordinates GLint viewport[4]; //normalized device coordinates -> window coordinates glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glGetDoublev(GL_PROJECTION_MATRIX, projection); // OpenGL uses a bottom-left origin, // however the click coordinates we receive use top-left origin.. GLdouble winX = (GLdouble)x; GLdouble winY = viewport[3] - (GLdouble)y; // Get intersection points for the 'near' and 'far' clipping planes GLdouble nearX, nearY, nearZ, farX, farY, farZ; gluUnProject(winX, winY, 0.0, modelview, projection, viewport, &nearX, &nearY, &nearZ); gluUnProject(winX, winY, 1.0, modelview, projection, viewport, &farX, &farY, &farZ); *nearPoint = Vec3Df(nearX, nearY, nearZ); *farPoint = Vec3Df(farX, farY, farZ); }
Hit ComplexObject::intersectBoundingBox(Vec3Df origin, Vec3Df dest) { // Our implementation is based on the ray-box intersection algorithm // as proposed here: http://people.csail.mit.edu/amy/papers/box-jgt.pdf // This section should be stored in a ray datastructure where it's cached Vec3Df direction = dest - origin; Vec3Df inverseDirection = Vec3Df(1/direction[0], 1/direction[1], 1/direction[2]); int sign[3]; sign[0] = (inverseDirection[0] < 0); sign[1] = (inverseDirection[1] < 0); sign[2] = (inverseDirection[2] < 0); // Intersection algorithm float xMin, yMin, zMin, xMax, yMax, zMax; xMin = (bounds[ sign[0] ][0] - origin[0]) * inverseDirection[0]; xMax = (bounds[ 1-sign[0] ][0] - origin[0]) * inverseDirection[0]; yMin = (bounds[ sign[1] ][1] - origin[1]) * inverseDirection[1]; yMax = (bounds[ 1-sign[1] ][1] - origin[1]) * inverseDirection[1]; zMin = (bounds[ sign[2] ][2] - origin[2]) * inverseDirection[2]; zMax = (bounds[ 1-sign[2] ][2] - origin[2]) * inverseDirection[2]; if ( (xMin > yMax) || (yMin > xMax) ) return noHit; if (yMin > xMin) xMin = yMin; if (yMax < xMax) xMax = yMax; if ( (xMin > zMax) || (zMin > xMax) ) return noHit; if (zMin > xMin) xMin = zMin; if (zMax < xMax) xMax = zMax; return Hit(1, Vec3Df(xMin, yMin, zMin), nullVector, defaultMaterial); }
void ComplexObject::initBoundingBox() { // Where we keep track of the following bounds float xMin = std::numeric_limits<float>::max(); float yMin = std::numeric_limits<float>::max(); float zMin = std::numeric_limits<float>::max(); float xMax = -std::numeric_limits<float>::max(); float yMax = -std::numeric_limits<float>::max(); float zMax = -std::numeric_limits<float>::max(); for (int triangle = 0; triangle < mesh.triangles.size(); triangle++) { Triangle T = mesh.triangles[triangle]; for (int vertex = 0; vertex < 3; vertex++) { Vertex V = mesh.vertices[T.v[vertex]]; Vec3Df vertexPosition = V.p; // X axis xMin = std::min(xMin, vertexPosition[0]); xMax = std::max(xMax, vertexPosition[0]); // Y axis yMin = std::min(yMin, vertexPosition[1]); yMax = std::max(yMax, vertexPosition[1]); // Z axis zMin = std::min(zMin, vertexPosition[2]); zMax = std::max(zMax, vertexPosition[2]); } } bounds[0] = Vec3Df(xMin, yMin, zMin); bounds[1] = Vec3Df(xMax, yMax, zMax); }
std::vector<Vec3Df> Projectile::getBoundingBox() { int temp = scale; scale = scale * 0.1f; Vec3Df topLeft = Vec3Df(position[0] - (width / 2.0f) * scale, position[1] - (height / 2.0f) * scale, position[2]); Vec3Df bottomRight = Vec3Df(position[0] + (width / 2.0f) * scale, position[1] + (height / 2.0f) * scale, position[2]); scale = temp; std::vector<Vec3Df> list = { topLeft, bottomRight }; return list; }
void updateCharacterMovementDirection() { // Update character movement Vec3Df direction = Vec3Df(0, 0, 0); if (keyPressed['w']) { direction += Vec3Df(0, 1, 0); } if (keyPressed['a']) { direction += Vec3Df(-1, 0, 0); } if (keyPressed['s']) { direction += Vec3Df(0, -1, 0); } if (keyPressed['d']) { direction += Vec3Df(1, 0, 0); } character.movementDirection = direction; }
std::vector<Vec3Df> Entity::getBoundingBox() { Vec3Df topLeft = Vec3Df(position[0] - (width / 2.0f) * scale, position[1] - (height / 2.0f) * scale, position[2]); Vec3Df bottomRight = Vec3Df(position[0] + (width / 2.0f) * scale, position[1] + (height / 2.0f) * scale, position[2]); //float angle = atan2f(movementDirection[1], movementDirection[0]); //float y = sin(angle) * (width / 2.0f); //float x = sin(angle) * (width / 2.0f); std::vector<Vec3Df> list = { topLeft, bottomRight }; return list; }
//take keyboard input into account void keyboard(unsigned char key, int x, int y) { //printf("Keydown %d, cursor pos (%d,%d)\n",key,x,y); //fflush(stdout); keyPressed[key] = true; if ((key>='1')&&(key<='9')) { DisplayMode= (DisplayModeType) (key-'0'); return; } updateCharacterMovementDirection(); switch (key) { case 'm': { if (MouseMode == MOUSE_MODE_SHOOTING) { MouseMode = MOUSE_MODE_CAMERA; } else if (MouseMode == MOUSE_MODE_CAMERA) { MouseMode = MOUSE_MODE_SHOOTING; } break; } case 27: // touche ESC exit(0); case 'L': //turn lighting on glEnable(GL_LIGHTING); break; case 'l': //turn lighting off glDisable(GL_LIGHTING); break; case 'b': spawnBoss(0); break; case 'j': if (boss.position[0] <= 0) boss.setDestination(Vec3Df(-2, -1, -0.5), 1); else boss.setDestination(Vec3Df(0, -1, -1), 1); break; case 'k': if (boss.position[0] >= 0) boss.setDestination(Vec3Df(2, -1, 0), 1); else boss.setDestination(Vec3Df(0, -1, 0.5), 1); break; case '+': meshIndex = ++meshIndex % meshes.size(); break; } }
/// Computes lighting for the entire scene void computeLighting() { for (auto &ridge : mountains) { for (int i=0; i < ridge.meshVertices.size(); i = i+3) { // Compute for our (single) light Vec3Df vertexpos = Vec3Df(ridge.meshVertices[i], ridge.meshVertices[i+1], ridge.meshVertices[i+2]); Vec3Df normal = Vec3Df(ridge.meshNormals[i], ridge.meshNormals[i+1], ridge.meshNormals[i+2]); Vec3Df lighting = computeLighting(vertexpos, normal, DIFFUSE_LIGHTING); // Pass computed values to Ridge ridge.meshColors[i] = lighting[0]; ridge.meshColors[i+1] = lighting[1]; ridge.meshColors[i+2] = lighting[2]; } } if (toggleBoss) { std::vector<Vertex> vertices = boss.getMesh().vertices; std::vector<Vec3Df> meshColors = std::vector<Vec3Df>(vertices.size()); auto rotMat = matrixMultiplication( rotateMatrixY(boss.angleHeadY*M_PI / 180), rotateMatrixX(boss.angleHeadZ*M_PI / 180) ); for (int i = 0; i < vertices.size(); i++) { // Compute for our (single) light Vertex vertex = vertices[i]; Vec3Df vec = vertex.p; vec = calculateMatrix(rotMat, vec); vec = vec + boss.translation; vec = vec * boss.scale; vec = vec + boss.position; Vec3Df nor = vertex.n; nor = calculateMatrix(rotMat, nor); nor = nor + boss.translation; nor = nor * boss.scale; nor = nor + boss.position; Vec3Df lighting = computeLighting(vec, nor, PHONG_LIGHTNING); meshColors[i] = lighting; } boss.getMesh().meshColor = meshColors; } }
float sRadius(float x, float y, float theta, const Image & img){ float pasX=(float) (NORME_PAS*cos((double)theta)); float pasY=(float) (NORME_PAS*sin((double)theta)); //courantD et courantG vont nous permettre de remonter le long de la courbe suivant le plan défini par theta Vec3Df courantD(x,y,0); float tailleCase = min(1/((float) img.sizeX),1/((float) img.sizeY)); Vec3Df pasG(pasX,pasY,0); pasG.normalize(); pasG*=-tailleCase; bool SolutionTrouvee=false; float radius=MINIMAL_RADIUS; while(true){ courantD+=Vec3Df(pasX,pasY,0); if(dehors(img,courantD)){ return radius; } float tangenteD = img.tangente(courantD[0],courantD[1],theta); Vec3Df oppose=Vec3Df(x,y,0); bool notFound=false; while(! img.estSous(oppose)){ oppose+= pasG; if(oppose[0]>1 || oppose[0]<0 || oppose[1]>1 || oppose[1]<0){ notFound=true; break; } } //si on a pas trouvé de correspondant on continue plus loin if(notFound){ if(SolutionTrouvee) return radius; else continue; } float tangenteOpp= img.tangente(oppose[0],oppose[1],theta); if(nearlyEgal(tangenteOpp,tangenteD)){ SolutionTrouvee=true; radius=Vec3Df::distance(Vec3Df(x,y,0),courantD); } } }
ComplexObject::ComplexObject(Mesh mesh) { this->mesh = mesh; Material defaultMaterial = Material(); nullVector = Vec3Df(0, 0, 0); noHit = Hit(0, nullVector, nullVector, defaultMaterial); initBoundingBox(); }
// Method parameter is required to be registered by glutTimerFunc() void spawnEnemy(int unusedValue) { // randomize the delay between enemies, with the base from the constant enemyRespawnDelay float delay = enemyRespawnDelay + ((rand() % 6 * 200) - 500); if (!toggleBoss) { Enemy enemy = Enemy(); enemy.position = Vec3Df(4, (rand() % 10 * 0.2 - 0.4), 0); enemy.movementDirection = Vec3Df(-1, 0, 0); enemies.push_back(enemy); // Repeat this glutTimerFunc(delay, spawnEnemy, 0); } }
/// Computes lighting for a single vertex with given calculation model. Vec3Df computeLighting(Vec3Df &vertexPos, Vec3Df &normal, LightModel lightModel) { const Vec3Df lightColor = Vec3Df(1,1,1); const Vec3Df lightColorBoss = Vec3Df(1, 0, 0); switch (lightModel) { case DIFFUSE_LIGHTING: { // We cheat here: assuming a distant sun, this is an reasonable approximation Vec3Df l = (Vec3Df(LightPos[0],LightPos[1],LightPos[2]) - Vec3Df(0,0,0)); l.normalize(); return Vec3Df::dotProduct(l, normal) * lightColor; } case PHONG_LIGHTNING: { Vec3Df lightDir = boss.position - vertexPos; lightDir.normalize(); Vec3Df reflDir = 2 * Vec3Df::dotProduct(lightDir, normal) * normal - lightDir; reflDir.normalize(); Vec3Df viewDir = camPos - vertexPos; viewDir.normalize(); //Using only 1 light source float ambiant = std::fmax(0, ka*ia); float diffuse = std::fmax(0, kd*Vec3Df::dotProduct(lightDir, normal)*id); float specular = std::fmax(0, ks*std::pow(std::fmax(0, Vec3Df::dotProduct(reflDir, viewDir)), alpha)*is); float intensity = ambiant + diffuse + specular; Vec3Df final = intensity * lightColorBoss; return final; } default: return Vec3Df(0, 0, 0); } }
inline void subdivide (std::vector<BoundingBox> & splitBoundingBoxArray) const { Vec3Df med = (minBb + maxBb) / 2; float x_2 = (maxBb[0] - minBb [0]) / 2; float y_2 = (maxBb[1] - minBb [1]) / 2; float z_2 = (maxBb[2] - minBb [2]) / 2; splitBoundingBoxArray.resize (8); splitBoundingBoxArray[0] = BoundingBox (minBb, med); splitBoundingBoxArray[1] = BoundingBox (minBb + Vec3Df (x_2, 0.0, 0.0), med + Vec3Df (x_2, 0.0, 0.0)); splitBoundingBoxArray[2] = BoundingBox (minBb + Vec3Df (0.0, y_2, 0.0), med + Vec3Df (0.0, y_2, 0.0)); splitBoundingBoxArray[3] = BoundingBox (minBb + Vec3Df (x_2, y_2, 0.0), med + Vec3Df (x_2, y_2, 0.0)); splitBoundingBoxArray[4] = BoundingBox (minBb + Vec3Df (0.0, 0.0, z_2), med + Vec3Df (0.0, 0.0, z_2)); splitBoundingBoxArray[5] = BoundingBox (minBb + Vec3Df (x_2, 0.0, z_2), med + Vec3Df (x_2, 0.0, z_2)); splitBoundingBoxArray[6] = BoundingBox (minBb + Vec3Df (0.0, y_2, z_2), med + Vec3Df (0.0, y_2, z_2)); splitBoundingBoxArray[7] = BoundingBox (minBb + Vec3Df (x_2, y_2, z_2), med + Vec3Df (x_2, y_2, z_2)); }
Vec3Df mouseToCharacterWorldPlane(int x, int y) { float xD = topLeft[0] + (((float)x) / W_fen) * (bottomRight[0] - topLeft[0]); float yD = topLeft[1] + (((float)y) / H_fen) * (bottomRight[1] - topLeft[1]); return Vec3Df(xD, yD, character.position[2]); }
// Because we use the shoulder position at multiple points, it is defined in this method. // Note that this position is a relative one! void Character::setShoulderPos() { shoulderPos = Vec3Df((-0.625f + (1.25f * turnAround)) * (width / 2.0f), 0.4f * (height / 2.0f), 0.0f); }
Vec3Df fromIrrVector3df(const irr::core::vector3df& vec) { return Vec3Df(vec.Z, vec.X, vec.Y); }
BoundingBox () : minBb (Vec3Df (FLT_MAX, FLT_MAX, FLT_MAX)), maxBb (Vec3Df (-FLT_MAX, -FLT_MAX, -FLT_MAX)) {}
OpponentSpaceShip::OpponentSpaceShip(float x, float y) { printf("-- OpponentSpaceShip \n"); SpaceShip::position = Vec3Df(x,y,0.0f); SpaceShip::bullitsShot = new std::vector<Bullet>(); }
// NOTE: In C++, declaring "Object instance;" will instantly call the Object constructor! // To do these forward declarations, use smart pointers (unique_ptr) instead. Character character = Character(); std::vector<Enemy> enemies = {}; std::vector<Projectile> projectiles = {}; std::vector<Mesh >meshes = {}; int glutElapsedTime = 0; //in ms bool keyPressed[256]; //keyboard buffer unique_ptr<Background> background; //smart pointer needed unique_ptr<Groundfloor> groundfloor; std::vector<Ridge> mountains; int numberOfRidges = 2; bool toggleBoss = false; Boss boss = Boss(Vec3Df(8, -1, -2), -1, 0.5);; // Game timing constants (in ms) const int firstEnemySpawnDelay = 3000; const int enemyRespawnDelay = 1500; const int bossSpawnDelay = 30000; //TODO remove this again int meshIndex = 0; //Phong model properties float is = 1.0f; float id = 1.0f; float ia = 0.1f; float ks = 1.0f;
Ecs::Entity createCharacter( Threading::ConcurrentWriter<Ecs::World>& world, const Vec3Df& position, const Vec3Df& rotation, const Statistics& statistics, const Ecs::Entity& group, Event::EventQueue& queue ) { // TODO: method AABB from model 3d AxisAlignedBoundingBox bbox( Vec3Df(-0.5, -0.5, 0.0), Vec3Df(0.5, 0.5, 2.0) ); Graphics::Render::AnimationMap animMap; animMap[Graphics::Render::Idle] = Graphics::Render::AnimationParameters(5.0f, true, Graphics::Render::NoAnimation); animMap[Graphics::Render::Walk] = Graphics::Render::AnimationParameters(5.0f, true, Graphics::Render::NoAnimation); animMap[Graphics::Render::Attack] = Graphics::Render::AnimationParameters(5.0f, true, Graphics::Render::NoAnimation); std::map<Character::Action::Type, Graphics::Render::AnimationType> animByAction; animByAction[Character::MoveAction::Type] = Graphics::Render::Walk; animByAction[Character::StopAction::Type] = Graphics::Render::Idle; animByAction[Character::StartHandAction::Type] = Graphics::Render::Attack; animByAction[Character::StopHandAction::Type] = Graphics::Render::Idle; const Ecs::Entity& entity = world->createEntity(); world->addComponent( entity, new PositionComponent(position) ); world->addComponent( entity, new RotationComponent(rotation) ); world->addComponent( entity, new Graphics::Render::RenderableComponent( "ninja.b3d", "" ) ); world->addComponent( entity, new Graphics::Render::AnimationComponent(animMap, animByAction) ); world->addComponent( entity, new Physics::MovementComponent(Vec3Df(0.0, 0.0, 0.0)) ); world->addComponent( entity, new Physics::GravityComponent(1) ); world->addComponent( entity, new Physics::CollisionComponent(new Physics::AABBCollisionBody(bbox)) ); world->addComponent( entity, new Character::StatisticsComponent( statistics ) ); world->addComponent( entity, new Character::CharacterComponent( statistics.getSpeed().getBaseValue(), group ) ); { Threading::ConcurrentWriter<GroupComponent> groupComponent = Threading::getConcurrentWriter<Ecs::Component, GroupComponent>( world->getEntityComponent(group, GroupComponent::Type) ); groupComponent->setCurrentHealth( groupComponent->getCurrentHealth() + statistics.getHealth().getBaseValue() ); } associateToGroup(world, entity, group, queue); return entity; }
inline void init (float x, float y, float z) { init (Vec3Df (x, y, z)); }
void SimpleTree::updateModel() { // TODO Split into several functions std::vector<Vec3Df> vertices; std::vector<Face> faces; std::vector<Vec2Df> base; // Building trunk base.push_back(Vec2Df(-trunkWidth_/2.0, -trunkWidth_/2.0)); base.push_back(Vec2Df(trunkWidth_/2.0, -trunkWidth_/2.0)); base.push_back(Vec2Df(trunkWidth_/2.0, trunkWidth_/2.0)); base.push_back(Vec2Df(-trunkWidth_/2.0, trunkWidth_/2.0)); const unsigned int length = base.size(); unsigned int baseIndex = 0; for (unsigned int i = 0; i < length; i++) { const Vec2Df& p1 = base[i]; const Vec2Df& p2 = base[(i + 1) % length]; vertices.push_back(Vec3Df(p1.getX(), p1.getY(), -4)); vertices.push_back(Vec3Df(p2.getX(), p2.getY(), -4)); vertices.push_back(Vec3Df(p2.getX(), p2.getY(), trunkHeight_)); vertices.push_back(Vec3Df(p1.getX(), p1.getY(), trunkHeight_)); faces.push_back(Face(baseIndex, baseIndex + 1, baseIndex + 2, trunkColor_)); faces.push_back(Face(baseIndex, baseIndex + 2, baseIndex + 3, trunkColor_)); baseIndex += 4; } // Building leaves base std::vector<Vec2Df> leavesBase; leavesBase.push_back(Vec2Df(-leavesWidth_/2.0 + offset_, -leavesWidth_/2.0)); leavesBase.push_back(Vec2Df(leavesWidth_/2.0 + offset_, -leavesWidth_/2.0)); leavesBase.push_back(Vec2Df(leavesWidth_/2.0 + offset_, leavesWidth_/2.0)); leavesBase.push_back(Vec2Df(-leavesWidth_/2.0 + offset_, leavesWidth_/2.0)); const unsigned int leavesLength = leavesBase.size(); for (unsigned int i = 0; i < leavesLength; i++) { const Vec2Df& point = leavesBase[i]; vertices.push_back(Vec3Df(point.getX(), point.getY(), trunkHeight_)); } for (unsigned int currentIndex = 1; currentIndex < leavesLength - 1; currentIndex++) { faces.push_back(Face( baseIndex, baseIndex + currentIndex + 1, baseIndex + currentIndex, leavesColor_ )); } baseIndex += leavesLength; if (form_.compare("cubique") == 0) { // Building leaves for (unsigned int i = 0; i < leavesLength; i++) { const Vec2Df& p1 = leavesBase[i]; const Vec2Df& p2 = leavesBase[(i + 1) % leavesLength]; vertices.push_back(Vec3Df(p1.getX(), p1.getY(), trunkHeight_)); vertices.push_back(Vec3Df(p2.getX(), p2.getY(), trunkHeight_)); vertices.push_back(Vec3Df(p2.getX(), p2.getY(), trunkHeight_ + leavesHeight_)); vertices.push_back(Vec3Df(p1.getX(), p1.getY(), trunkHeight_ + leavesHeight_)); faces.push_back(Face(baseIndex, baseIndex + 1, baseIndex + 2, leavesColor_)); faces.push_back(Face(baseIndex, baseIndex + 2, baseIndex + 3, leavesColor_)); baseIndex += 4; } // Building leaves top for (unsigned int i = 0; i < leavesLength; i++) { const Vec2Df& point = leavesBase[i]; vertices.push_back(Vec3Df(point.getX(), point.getY(), trunkHeight_ + leavesHeight_)); } for (unsigned int currentIndex = 1; currentIndex < leavesLength - 1; currentIndex++) { faces.push_back( Face( baseIndex, baseIndex + currentIndex, baseIndex + currentIndex + 1, leavesColor_ ) ); } } else { // Building leaves Vec2Df center; for (unsigned int i = 0; i < leavesLength; i++) { center += leavesBase[i]; } center /= leavesLength; for (unsigned int i = 0; i < leavesLength; i++) { const Vec2Df& p1 = leavesBase[i]; const Vec2Df& p2 = leavesBase[(i + 1) % leavesLength]; vertices.push_back(Vec3Df(p1.getX(), p1.getY(), trunkHeight_)); vertices.push_back(Vec3Df(p2.getX(), p2.getY(), trunkHeight_)); vertices.push_back(Vec3Df(center.getX(), center.getY(), trunkHeight_ + leavesHeight_)); faces.push_back(Face(baseIndex, baseIndex + 1, baseIndex + 2, leavesColor_)); baseIndex += 3; } } model_ = Model3D(vertices, faces); }
void KDTree::Node::buildNode(const KDTree& tree, int maxDepth) { // Find the median plan Vec3Df n; if (boundingBox.getSize() == boundingBox.getWidth() ){ n = Vec3Df (boundingBox.getMax()[0] - boundingBox.getMin()[0], 0.0, 0.0); } else if (boundingBox.getSize() == boundingBox.getHeight()){ n = Vec3Df (0.0, boundingBox.getMax()[1] - boundingBox.getMin()[1], 0.0); } else{ n = Vec3Df( 0.0, 0.0, boundingBox.getMax()[2] - boundingBox.getMin()[2]); } n.normalize(); Vec3Df position = getMedianPoint(tree.getMesh(), n);; plan.n = n; plan.position = position; if (depth == maxDepth) { return; } //seperate triangles vector<int> leftIndexes, rightIndexes; for (int idx : triangleIndexes){ const Triangle& t = tree.getMesh().getTriangles()[idx]; const Vec3Df& a = tree.getMesh().getVertices()[ t.getVertex(0)].getPos(); const Vec3Df& b = tree.getMesh().getVertices()[ t.getVertex(1)].getPos(); const Vec3Df& c = tree.getMesh().getVertices()[ t.getVertex(2)].getPos(); //regarder si tous les sommets sont du même côté du plan... if ( plan.isLeft(a) && plan.isLeft(b) && plan.isLeft(c) ){ //Ils sont tous à gauche leftIndexes.push_back(idx); } else if( plan.isRight(a) && plan.isRight(b) && plan.isRight(c) ){ //Ils sont tous à droite rightIndexes.push_back(idx); } else { // Le triangle doit être ajouté des deux côtés rightIndexes.push_back(idx); leftIndexes.push_back(idx); } } if(rightIndexes == leftIndexes) return; if (triangleIndexes.size() == rightIndexes.size() || triangleIndexes.size() == leftIndexes.size()) return; if(rightIndexes.size() != 0){ right_node = new KDTree::Node(rightIndexes, depth + 1, tree); right_node->buildNode(tree, maxDepth); } if(leftIndexes.size() != 0){ left_node = new KDTree::Node(leftIndexes, depth + 1, tree); left_node->buildNode(tree, maxDepth); } }
inline Light () : color (Vec3Df (1.0f, 1.0f, 1.0f)), intensity (1.0f) {}
Ecs::Entity createAttackArea( Threading::ConcurrentWriter<Ecs::World>& world, const Ecs::Entity& character ) { Ecs::Entity area = world->createEntity(); Vec3Df basePosition; Vec3Df rotation; unsigned int damages = 0; { Ecs::ComponentGroup::ComponentTypeCollection types; types.insert(StatisticsComponent::Type); types.insert(CharacterComponent::Type); types.insert(PositionComponent::Type); types.insert(RotationComponent::Type); Ecs::ComponentGroup prototype(types); Ecs::ComponentGroup group = world->getEntityComponents( character, prototype ); Threading::ConcurrentWriter<CharacterComponent> characterComponent = Threading::getConcurrentWriter<Ecs::Component, CharacterComponent>( group.getComponent(CharacterComponent::Type) ); Threading::ConcurrentReader<StatisticsComponent> statComponent = Threading::getConcurrentReader<Ecs::Component, StatisticsComponent>( group.getComponent(StatisticsComponent::Type) ); Threading::ConcurrentReader<PositionComponent> posComponent = Threading::getConcurrentReader<Ecs::Component, PositionComponent>( group.getComponent(PositionComponent::Type) ); Threading::ConcurrentReader<RotationComponent> rotComponent = Threading::getConcurrentReader<Ecs::Component, RotationComponent>( group.getComponent(RotationComponent::Type) ); damages = statComponent->getStatistics().getAttack().getCurrentValue(); characterComponent->setAttackArea(area); basePosition = posComponent->getPosition(); rotation = rotComponent->getRotation(); } Geometry::Vec2Df offset = Geometry::Vec2Df::fromPolar( rotation.getZ(), 1.5 ) - Geometry::Vec2Df(0.5, 0.5); Geometry::AxisAlignedBoundingBox bbox( Geometry::Vec3Df(0.0, 0.0, 0.0), Geometry::Vec3Df(1.0, 1.0, 1.0) ); world->addComponent(area, new PositionComponent( basePosition + Vec3Df(offset.getX(), offset.getY(), 0) )); world->addComponent(area, new RotationComponent( Vec3Df(0, 0, 0) )); world->addComponent(area, new Physics::CollisionComponent( new Physics::AABBCollisionBody(bbox) )); world->addComponent(area, new HarmComponent( damages )); return area; }
void Tessellation3D::setVertex(UInt idx, float x, float y, float z) { _vertices[idx] = new Vertex(); _vertices[idx]->pos = Vec3Df(x, y, z); _vertices[idx]->normal = Vec3Df(0.f, 0.f, 0.f); }