bool Ray::intersectAABB(const AABB &aabb) const { Vector3d dirFrac; dirFrac.x() = 1.0f / _direction.x(); dirFrac.y() = 1.0f / _direction.y(); dirFrac.z() = 1.0f / _direction.z(); float t1 = (aabb.getMin().x() - _origin.x()) * dirFrac.x(); float t2 = (aabb.getMax().x() - _origin.x()) * dirFrac.x(); float t3 = (aabb.getMin().y() - _origin.y()) * dirFrac.y(); float t4 = (aabb.getMax().y() - _origin.y()) * dirFrac.y(); float t5 = (aabb.getMin().z() - _origin.z()) * dirFrac.z(); float t6 = (aabb.getMax().z() - _origin.z()) * dirFrac.z(); float tMin = MAX(MAX(MIN(t1, t2), MIN(t3, t4)), MIN(t5, t6)); float tMax = MIN(MIN(MAX(t1, t2), MAX(t3, t4)), MAX(t5, t6)); // If tMax < 0, the ray is intersecting the AABB, but the whole AABB is in the opposite direction if (tMax < 0) { return false; } // If tMin > tMax, the ray doesn't intersect the AABB if (tMin > tMax) { return false; } return true; }
void Collide::pointBoxCollide(const Body * point_, const Body * box) { Point *point = (Point*)point_; AABB *aabb = (AABB*)box; if (point->getPoint().GetX() > aabb->getMin().GetX() && point->getPoint().GetX() < aabb->getMax().GetX() && point->getPoint().GetY() > aabb->getMin().GetY() && point->getPoint().GetY() < aabb->getMax().GetY() && point->getPoint().GetZ() > aabb->getMin().GetZ() && point->getPoint().GetZ() < aabb->getMax().GetZ()) { setCollide(true); // haven't calculate the distance setDistance(-1); } else { setCollide(false); // haven't calculate the distance setDistance(1); } // compute the response vectors Vector3 responseObject1 = point_->getCenter() - box->getCenter(); Vector3 responseObject2 = box->getCenter() - point_->getCenter(); setResponseObject1(responseObject1); setResponseObject2(responseObject2); }
AABB<3, T> operator*(const Transform<T>& lhs, const AABB<3, T>& rhs) { Vector<3, T> min = lhs.getScale() * rhs.getMin(); Vector<3, T> max = lhs.getScale() * rhs.getMax(); const Vector<3, T> corners[8] = { Vector<3, T>(min.x, min.y, min.z), Vector<3, T>(min.x, min.y, max.z), Vector<3, T>(min.x, max.y, min.z), Vector<3, T>(min.x, max.y, max.z), Vector<3, T>(max.x, min.y, min.z), Vector<3, T>(max.x, min.y, max.z), Vector<3, T>(max.x, max.y, min.z), Vector<3, T>(max.x, max.y, max.z), }; min.x = min.y = min.z = std::numeric_limits<T>::max(); max.x = max.y = max.z = std::numeric_limits<T>::min(); for (std::size_t i = 0; i < 8; ++i) { Vector<3, T> v = lhs.getRotation() * corners[i]; min.x = std::min(min.x, v.x); min.y = std::min(min.y, v.y); min.z = std::min(min.z, v.z); max.x = std::max(max.x, v.x); max.y = std::max(max.y, v.y); max.z = std::max(max.z, v.z); } return AABB<3, T>(lhs.getTranslation() + min, lhs.getTranslation() + max); }
bool AABB::isColliding(const AABB & box) const { const Vector2 bMin = box.getMin(); const Vector2 bMax = box.getMax(); return bMin.getX() < m_max.getX() && bMax.getX() > m_min.getX() && bMin.getY() < m_max.getY() && bMax.getY() > m_min.getY(); }
bool Frustum::inside(AABB const& aabb) const { glm::vec3 minimum = aabb.getMin(); glm::vec3 maximum = aabb.getMax(); //for each plane do ... glm::vec3 pos; glm::vec3 neg; bool result = true; for(int i = 0; i < FrustumPlane::NUM_PLANES; ++i) { pos = minimum; neg = maximum; if (mPlanes[i].normal.x > 0.f) { pos.x = maximum.x; neg.x = minimum.x; } if (mPlanes[i].normal.y > 0.f) { pos.y = maximum.y; neg.y = minimum.y; } if (mPlanes[i].normal.z > 0.f) { pos.z = maximum.z; neg.z = minimum.z; } // is the positive vertex outside? if (mPlanes[i].distance(pos) < 0.f) { return false; } // is the negative vertex outside? else if (mPlanes[i].distance(neg) < 0.f) result = true; // intersection } return result; }
bool AABB::isCollide(AABB& a) { const float * a_min = a.getMin(); const float * a_max = a.getMax(); if (min_v[0] > a_max[0]) return false; if (max_v[0] < a_min[0]) return false; if (min_v[1] > a_max[1]) return false; if (max_v[1] < a_min[1]) return false; if (min_v[2] > a_max[2]) return false; if (max_v[2] < a_min[2]) return false; return true; }
std::shared_ptr<OctreeSDF> OctreeSDF::sampleSDF(SolidGeometry* otherSDF, const AABB& aabb, int maxDepth) { auto ts = Profiler::timestamp(); std::shared_ptr<OctreeSDF> octreeSDF = std::make_shared<OctreeSDF>(); Ogre::Vector3 aabbSize = aabb.getMax() - aabb.getMin(); float cubeSize = std::max(std::max(aabbSize.x, aabbSize.y), aabbSize.z); octreeSDF->m_CellSize = cubeSize / (1 << maxDepth); otherSDF->prepareSampling(aabb, octreeSDF->m_CellSize); octreeSDF->m_RootArea = Area(Vector3i(0, 0, 0), maxDepth, aabb.getMin(), cubeSize); octreeSDF->m_RootNode = octreeSDF->createNode(octreeSDF->m_RootArea, *otherSDF); Profiler::printJobDuration("OctreeSDF::sampleSDF", ts); return octreeSDF; }
wiSPTree* wiSPTree::updateTree(Node* node){ if(this && node) { vector<Cullable*> bad(0); for(Cullable* object : node->objects){ #ifdef SP_TREE_BOX_CONTAIN if( node->box.intersects(object->bounds)!=AABB::INSIDE ) #else if( !node->box.intersects(object->translation) ) #endif bad.push_back(object); } if(!bad.empty()){ for(Cullable* object : bad){ node->objects.remove(object); } if(node->parent){ AddObjects(node->parent,bad); } else{ CulledList culledItems; getVisible(node,node->box,culledItems); for(Cullable* item : culledItems){ bad.push_back(item); } wiSPTree* tree; if(childCount==8) tree = new Octree(); else tree = new QuadTree(); AABB nbb = node->box*1.5; tree->initialize(bad,nbb.getMin(),nbb.getMax()); return tree; } } if(!node->children.empty()){ for (unsigned int i = 0; i<node->children.size(); ++i) updateTree(node->children[i]); } } return NULL; }
/// NOTE: Expects @param nodes to be a link list along the left child AABB::AABB(AABB *nodes) : left(0), right(0), move(0) { if (!nodes) return; // Compute bounds unsigned count = 0; for (AABB *it = nodes; it; it = it->left) { if (it->right) THROW("Unexpected right-hand AABB node"); add(*it); count++; } // Degenerate cases if (count < 3) { if (count == 2) right = nodes->left; left = nodes->prepend(0); return; } // Decide split unsigned axis = getDimensions().findLargest(); real cut = getMax()[axis] + getMin()[axis]; // Partition nodes AABB *lessThan = 0; AABB *greaterThan = 0; unsigned lessCount = 0; unsigned greaterCount = 0; for (AABB *it = nodes; it;) { AABB *next = it->left; bool less = it->getMax()[axis] + it->getMin()[axis] < cut; if (less) {lessThan = it->prepend(lessThan); lessCount++;} else {greaterThan = it->prepend(greaterThan); greaterCount++;} it = next; } // Check for bad partition if (!lessThan) lessThan = greaterThan->split(greaterCount / 2); if (!greaterThan) greaterThan = lessThan->split(lessCount / 2); // Recur left = new AABB(lessThan); right = new AABB(greaterThan); }
void OverlayBatch::addOverlay(const AABB<2, float>& bounds, const AABB<2, float>& imageRegion, const Vector<4, float>& color) { if (isFull()) { throw MemoryException("Overlay batch exceeded capacity."); } float vertices[4][9]; vertices[0][0] = bounds.getMax().x; vertices[0][1] = bounds.getMin().y; vertices[0][2] = 0.0f; vertices[0][3] = imageRegion.getMax().x; vertices[0][4] = imageRegion.getMax().y; vertices[0][5] = color.r; vertices[0][6] = color.g; vertices[0][7] = color.b; vertices[0][8] = color.a; vertices[1][0] = bounds.getMin().x; vertices[1][1] = bounds.getMin().y; vertices[1][2] = 0.0f; vertices[1][3] = imageRegion.getMin().x; vertices[1][4] = imageRegion.getMax().y; vertices[1][5] = color.r; vertices[1][6] = color.g; vertices[1][7] = color.b; vertices[1][8] = color.a; vertices[2][0] = bounds.getMin().x; vertices[2][1] = bounds.getMax().y; vertices[2][2] = 0.0f; vertices[2][3] = imageRegion.getMin().x; vertices[2][4] = imageRegion.getMin().y; vertices[2][5] = color.r; vertices[2][6] = color.g; vertices[2][7] = color.b; vertices[2][8] = color.a; vertices[3][0] = bounds.getMax().x; vertices[3][1] = bounds.getMax().y; vertices[3][2] = 0.0f; vertices[3][3] = imageRegion.getMax().x; vertices[3][4] = imageRegion.getMin().y; vertices[3][5] = color.r; vertices[3][6] = color.g; vertices[3][7] = color.b; vertices[3][8] = color.a; vertexBuffer->setData(vertices, overlayCount * 4, 4); ++overlayCount; }
AABB<N, T> operator*(const Matrix<N + 1, N + 1, T>& lhs, const AABB<N, T>& rhs) { Vector<N, T> min(lhs[N]); Vector<N, T> max(lhs[N]); for (std::size_t i = 0; i < N; ++i) { for (std::size_t j = 0; j < N; ++j) { T a = lhs[i][j] * rhs.getMin()[j]; T b = lhs[i][j] * rhs.getMax()[j]; min[i] += std::min(a, b); max[i] += std::max(a, b); } } return AABB<N, T>(min, max); }
// If AABB intersects the frustum, an output clip mask is returned as well (indicating which // planes are crossed by the AABB). This information can be used to optimize testing of // child nodes or objects inside the nodes (pass value as 'inClipMask'). bool intersectAABBFrustum (const AABB& a, const Vector4* p, unsigned int& outClipMask, unsigned int inClipMask) { Vector3 m = a.getCenter(); // center of AABB Vector3 d = a.getMax() - m; // half-diagonal unsigned int mk = 1; outClipMask = 0; // init outclip mask while (mk <= inClipMask){ // loop while there are active planes.. if (inClipMask&mk){ // if clip plane is active... float NP = (float)(d.x*fabs(p->x)+d.y*fabs(p->y)+d.z*fabs(p->z)); float MP = m.x*p->x+m.y*p->y+m.z*p->z+p->w; if ((MP+NP) < 0.0f) return false; // behind clip plane if ((MP-NP) < 0.0f) outClipMask |= mk; } mk+=mk; // mk = (1<<iter) p++; // next plane } return true; // AABB intersects frustum }
void AABB::include(const AABB& other) { include(other.getMin()); include(other.getMax()); }
KdTreeBase::SplitCandidate KdTreeSahNlog2N::determineSplitpos(const AABB& v, const unsigned int* primitves, const unsigned int primitveCount) { SAHCost bestCost(false, 10000.0f); SAHCost currentCost; SplitCandidate currentSplit; SplitCandidate bestSplit = { 0.0f, 3, false}; bestSplit.axis = 3; // to mark that there's been no good one yet for (unsigned int axis = 0; axis < 3; ++axis) { List<KdTreeSahNlog2N::Event>events; events.reserve(primitveCount * 2); for ( unsigned int p = 0; p < primitveCount; ++p) { const Primitive& currentPrimitive = scene.getPrimitive(primitves[p]); const AABB& currBB = getAABBForPrimitiv(primitves[p]); if ( (currentPrimitive.getNormal() == AXIS[axis]) || (( -1.0 * currentPrimitive.getNormal()) == AXIS[axis])) { events.push_back(Event(fmaxf(currBB.getMin(axis), v.getMin(axis)), INPLANE)); } else { events.push_back(Event(fmaxf(currBB.getMin(axis), v.getMin(axis)), START)); events.push_back(Event(fminf(currBB.getMax(axis), v.getMax(axis)), END)); } } sort(events.begin(), events.end()); unsigned int inplane = 0, leftOf = 0, rightOf = primitveCount; currentSplit.axis = axis; unsigned int dend, dstart, dplane; List<Event>::const_iterator iter = events.begin(); // for (; iter != events.end(); ++iter) { // std::cout << (*iter).t << ":"; // switch((*iter).type) { // case START: std::cout << "START";break; // case END: std::cout << "END";break; // case INPLANE: std::cout << "PLANE";break; // } // std::cout << "\n"; // } // iter = events.begin(); while (iter != events.end()) { dend = dstart = dplane = 0; currentSplit.pos = (*iter).t; while ( (iter != events.end()) && ((*iter).t == currentSplit.pos ) && (*iter).type == END ) { ++dend; ++iter; } while ( (iter != events.end()) && ((*iter).t == currentSplit.pos ) && (*iter).type == INPLANE ) { ++dplane; ++iter; } while ( (iter != events.end()) && ((*iter).t == currentSplit.pos ) && (*iter).type == START ) { ++dstart; ++iter; } inplane = dplane; leftOf -= dplane; rightOf -= dend; currentCost = SAH(v, currentSplit , leftOf, rightOf, inplane); // std::cout << currentSplit.pos << ":" << currentCost<< "," << leftOf << ","<< rightOf << ","<< inplane << "\n"; if ( currentCost < bestCost ) { bestCost = currentCost; bestSplit = currentSplit; bestSplit.putInPlaneLeft = bestCost.putInPlaneLeft; } leftOf += dstart; leftOf += dplane; inplane = 0; } } // std::cout << std::endl; return bestSplit; }
void LightComponent::_prePassIterationRendering( Pass const* pass, int iterationIndex, CameraComponent const* mainCamera, glm::mat4 const& mainCameraSpaceMatrix, glm::mat4& passProjectionMatrix, glm::mat4& passCameraSpaceMatrix, AABB const& worldAABB ) { if( pass->getPov() == PointOfView::LOCAL && pass->getRenderTarget().getRenderTargetType() == RenderTargetType::RT_2D_ARRAY && mType == LightType::DIRECTIONAL) { // prepare to render Cascaded Shadow Maps // -> set the model view matrix to look into light direction passCameraSpaceMatrix = glm::lookAt(glm::vec3(),-getTransformedDirection(), glm::vec3(-1.f, 0.f, 0.f)); setupFrustumPoints( iterationIndex, mainCamera->getViewportWidth(), mainCamera->getViewportHeight(), mainCamera->getFovY(), mainCameraSpaceMatrix, glm::inverse(mainCameraSpaceMatrix), mainCamera->getInverseCameraRotation() ); // APPLY CROP MATRIX TO PROJECTION MATRIX float maxX = -FLT_MAX; float maxY = -FLT_MAX; float maxZ; float minX = FLT_MAX; float minY = FLT_MAX; float minZ; glm::mat4 nv_mvp; glm::vec4 transf; // find the z-range of the current frustum as seen from the light // in order to increase precision // note that only the z-component is need and thus // the multiplication can be simplified // transf.z = shad_modelview[2] * f.point[0].x + shad_modelview[6] * f.point[0].y + shad_modelview[10] * f.point[0].z + shad_modelview[14]; // frustum points are in inverse camera space! // passCameraSpaceMatrix contains lookAt of light! transf = passCameraSpaceMatrix*mLightEffectState->frustumPoints[iterationIndex*8]; minZ = transf.z; maxZ = transf.z; for(int l=1; l<8; l++) { transf = passCameraSpaceMatrix*mLightEffectState->frustumPoints[iterationIndex*8+l]; if(transf.z > maxZ) maxZ = transf.z; if(transf.z < minZ) minZ = transf.z; } // @todo only a hack, because there is some bug in aabb retrieval of hole scene (value here should be reseted to 1.0 which was the default). float radius = 0.0; // make sure all relevant shadow casters are included // note that these here are dummy objects at the edges of our scene // @todo here we should use the AABB of the hole Scene transf.z = worldAABB.getMin().z; if(transf.z + radius > maxZ) maxZ = transf.z + radius; if(transf.z - radius < minZ) minZ = transf.z - radius; transf.z = worldAABB.getMax().z; if(transf.z + radius > maxZ) maxZ = transf.z + radius; if(transf.z - radius < minZ) minZ = transf.z - radius; // set the projection matrix with the new z-bounds // note the inversion because the light looks at the neg. z axis // gluPerspective(LIGHT_FOV, 1.0, maxZ, minZ); // for point lights passProjectionMatrix = glm::ortho(-1.f,1.f,-1.f,1.f,-maxZ,-minZ); glm::mat4 shadowModelViewProjection = passProjectionMatrix * passCameraSpaceMatrix; // find the extends of the frustum slice as projected in light's homogeneous coordinates for(int l=0; l<8; l++) { transf = shadowModelViewProjection*mLightEffectState->frustumPoints[iterationIndex*8+l]; transf.x /= transf.w; transf.y /= transf.w; if(transf.x > maxX) maxX = transf.x; if(transf.x < minX) minX = transf.x; if(transf.y > maxY) maxY = transf.y; if(transf.y < minY) minY = transf.y; } float scaleX = 2.0f/(maxX - minX); float scaleY = 2.0f/(maxY - minY); float offsetX = -0.5f*(maxX + minX)*scaleX; float offsetY = -0.5f*(maxY + minY)*scaleY; // apply a crop matrix to modify the projection matrix we got from glOrtho. glm::mat4 cropMatrix; cropMatrix = glm::translate(cropMatrix, glm::vec3(offsetX, offsetY,0.0f) ); cropMatrix = glm::scale(cropMatrix, glm::vec3( scaleX, scaleY, 1.0f) ); // adjust the view frustum of the light, so that it encloses the camera frustum slice fully. // note that this function calculates the projection matrix as it sees best fit passProjectionMatrix = cropMatrix * passProjectionMatrix; glm::mat4 passMVP = passProjectionMatrix*passCameraSpaceMatrix; //mShadowDescriptor.setOrthoFrustum(iterationIndex, passMVP); // build up a matrix to transform a vertex from eye space to light clip space mLightEffectState->eyeToLightClip[iterationIndex] = BIAS * passMVP * glm::inverse(mainCameraSpaceMatrix); // farClip[i] is originally in eye space - tells us how far we can see. // Here we compute it in camera homogeneous coordinates. Basically, we calculate // cam_proj * (0, 0, f[i].fard, 1)^t and then normalize to [0; 1] mLightEffectState->farClipsHomogenous[iterationIndex] = 0.5f*(-mLightEffectState->farClips[iterationIndex]*glm::value_ptr(mainCamera->getProjectionMatrix())[10]+glm::value_ptr(mainCamera->getProjectionMatrix())[14])/mLightEffectState->farClips[iterationIndex] + 0.5f; } }
void Player::update(float deltaTime) { checkMapStatus(); vec3f initPos = pos; //Animation Conditions bool collidingSides = false; bool collidingFloor = false; bool running = false; //PHYSICS // apply forces vec3f dir(0); if(input.getKeyState(InputHandler::PLAYER_LEFT)) { dir += vec3f(-1, 0, 0); running = true; } if(input.getKeyState(InputHandler::PLAYER_RIGHT)) { dir += vec3f(1, 0, 0); running = true; } vec3f friction(0); if(!(fabs(velocity.x) < 0.08f)) friction = FRICTION_COEFF*vec3f(velocity.x > 0 ? -1.0 : 1.0, 0, 0); totalForce += ACCELERATION*dir + vec3f(0, -GRAVITY, 0) + friction; bool saltito = false; // apply impulses if (animState != Player::JUMP && input.getKeyDown(InputHandler::PLAYER_UP)) { velocity.y += JUMP_IMPULSE; saltito = true; } // integration velocity = glm::clamp(velocity + totalForce*deltaTime, vec3f(-MAX_VELOCITY), vec3f(MAX_VELOCITY)); if (fabs(velocity.x) < 0.08f) velocity.x = 0; //Reset totalForce; totalForce = vec3f(0.0f); vec3f disp = velocity*deltaTime; //NOT PHYSICS // collision detection Map* map = (Map*)getGame()->getObjectByName("map"); AABB aabb = modelAabb; mat4f trans = fullTransform*modelOffset; aabb = AABB(vec3f(trans*vec4f(aabb.getMin(), 1.0f)), vec3f(trans*vec4f(aabb.getMax(), 1.0f))); vec3f bbmin = vec3f(trans*vec4f(modelAabb.getMin(), 1.0f)); vec3f bbmax = vec3f(trans*vec4f(modelAabb.getMin() + modelAabb.getDimensions()*vec3f(0.2f, 0.05f, 1.0f), 1.0f)); AABB brushBox(bbmin + disp, bbmax + disp); colliding = false; bool isBrushColliding = false; //Y AABB newboxY(aabb.getMin()+vec3f(0,disp.y,0), aabb.getMax()+vec3f(0,disp.y,0)); Color blockColor; if(map->isColliding(newboxY, blockColor)) { float min = 0; float max = 1; Color foo; isBrushColliding = map->isColliding(brushBox, foo); while(max-min > 0.001) { //search for the maximum distance you can move float m = (max+min)/2; newboxY = AABB(aabb.getMin()+vec3f(0,disp.y*m,0), aabb.getMax()+vec3f(0,disp.y*m,0)); if(map->isColliding(newboxY, foo)) max = m; else min = m; } if(velocity.y < 0) collidingFloor = true; velocity.y = 0; disp.y *= min; colliding = true; isBrushColliding = true; } pos.y += disp.y; aabb = AABB(aabb.getMin()+vec3f(0,disp.y,0), aabb.getMax()+vec3f(0,disp.y,0)); //X bool isRightWall = false; AABB newboxX(aabb.getMin()+vec3f(disp.x,0,0), aabb.getMax()+vec3f(disp.x,0,0)); if(map->isColliding(newboxX, blockColor)) { Color foo; isBrushColliding = isBrushColliding || map->isColliding(brushBox, foo); float min = 0; float max = 1; while(max-min > 0.001) { //search for the maximum distance you can move float m = (max+min)/2; newboxX = AABB(aabb.getMin()+vec3f(disp.x*m,0,0), aabb.getMax()+vec3f(disp.x*m,0,0)); if(map->isColliding(newboxX, foo)) max = m; else min = m; } //WALL JUMP vec3f wallFriction(0); if(velocity.x != 0) { wallFriction = FRICTION_COEFF*vec3f(0, velocity.y > 0 ? -.1 : .4, 0); collidingSides = true; } totalForce += wallFriction; if(velocity.x > 0 ) { if (input.getKeyDown(InputHandler::PLAYER_UP)) { velocity.x -= JUMP_IMPULSE*5; emitter->boomSide(20, -1); saltito = false; } isRightWall = true; } else if(velocity.x < 0 ) { if (input.getKeyDown(InputHandler::PLAYER_UP)) { velocity.x += JUMP_IMPULSE*5; emitter->boomSide(20, 1); saltito = false; } } else velocity.x = 0; disp.x *= min; colliding = true; } if(saltito) emitter->boom(20); pos.x += disp.x; //ANIMATION if(collidingSides) { animState = Player::WALL; anim = velocity.y > 0 ? "wallu" : "walld"; } else if(collidingFloor) { if(running) { animState = Player::RUN; anim = fabs(velocity.x) >= MAX_VELOCITY/2 ? "runb" : "runa"; } else { animState = Player::IDLE; anim = "idle"; } } else { animState = Player::JUMP; anim = fabs(velocity.x) > MAX_VELOCITY/2 ? "jumpb" : "jumpa"; } animCount += deltaTime; if(animCount >= animTime) { animCount -= animTime; animTime = randomFloat(0.1f, 0.2f); animIter = 1 - animIter; } std::string s = "brush" + anim + toString(animIter); model.mesh = Meshes.get(s); // TRAILS if(collidingFloor && !prevOnfloor) emitter->boom(20); if (collidingFloor && isBrushColliding && (blockColor == Color::WHITE || blockColor == color) ) { Trails* trails = (Trails*)getGame()->getObjectByName("trails"); trails->addTrailSegment(color, Trails::HORIZONTAL, pos.x, initPos.x, int(pos.y - 0.1), 1.5f*modelAabb.getDimensions().x); } if (collidingSides && isBrushColliding && (blockColor == Color::WHITE || blockColor == color) ) { Trails* trails = (Trails*)getGame()->getObjectByName("trails"); Trails::Direction dir; if (isRightWall) dir = Trails::VERTICAL_RIGHT; else dir = Trails::VERTICAL_LEFT; float off = 0.21; trails->addTrailSegment(color, dir, pos.y-off, initPos.y-off, int(pos.x+(isRightWall?1:0)), 1.5f*modelAabb.getDimensions().x); } prevOnfloor = collidingFloor; prevOnside = collidingSides; //transform stuff for(int i = 0; i < 3; ++i) { if(rot[i] < 0) rot[i] = rot[i]+360; else if(rot[i] >= 360.0f) rot[i] = rot[i]-360; } transform = glm::translate(mat4f(1), pos); transform = glm::scale(transform, scale); if(pos.y < -2) die(); }
AABB::AABB(const AABB ©) { min = copy.getMin(); max = copy.getMax(); }