/*! * \brief Create a new BoundingVolume object. * * This method creates and returns a new BoundingVolume object, according to * the preferred BoundingVolume-type settings. * * \param parent The BvhNode that the BoundingVolume should be in. See \ref * setHierarchyNode. * * \return A new BoundingVolume object. The caller is responsible for * deleting it. */ BoundingVolume* BoundingVolume::createBoundingVolume(World* world, BvhNode* parent) { if (!world) { throw NullPointerException("Parameter world"); } BoundingVolume* bv = 0; switch (getCreateRigidBoundingVolumeType(world)) { case BV_TYPE_AABB: bv = new Aabb(); break; case BV_TYPE_KDOP: bv = new Kdop(); break; case BV_TYPE_SPHERE: bv = new BoundingSphere(); break; case BV_TYPE_OBB: bv = new Obb(); break; default: // TODO: exception!! std::cerr << dc_funcinfo << "FATAL ERROR: bounding volume type " << getCreateRigidBoundingVolumeType(world) << " not supported" << std::endl; exit(1); return 0; } bv->setHierarchyNode(parent); return bv; }
BoundingVolume Grid::boundingVolume(const Math::Transformation &transformation) const { BoundingVolume volume; for (const Vertex &vertex : mVertices) { volume.expand(transformation * vertex.point); } return volume; }
/*! * \brief Tests for intersection with another Aabb * \return TRUE If this Aabb intersects with \p other. Otherwise FALSE. * * TODO: Implement correct/faster collision detection methods for * collisions between different types of bounding volumes. */ bool Aabb::collidesWith(const BoundingVolume& other) const { if (other.getVolumeType() == getVolumeType()) { const BoundingVolume* otherPointer = &other; const Aabb* aabbPointer = static_cast<const Aabb*>(otherPointer); return collidesWithInternal(*aabbPointer); } return collidesWithInternal(Aabb(other.getSurroundingAabbMin(), other.getSurroundingAabbMax())); }
bool Physics::willObjectsCollide(CollidableObject* coA, CollidableObject* coB) { PhysicalProperties* pp = coA->getPhysicalProperties(); BoundingVolume* bv = coA->getBoundingVolume(); float widthA = bv->getWidth(); float heightA = bv->getHeight(); float xA = pp->getX() + bv->getX(); float yA = pp->getY() + bv->getY(); float velXA = pp->getVelocityX(); float velYA = pp->getVelocityY(); float minXA = xA-(widthA/2); float maxXA = xA+(widthA/2); float minYA = yA-(heightA/2); float maxYA = yA+(heightA/2); if(velXA >= 0) maxXA += velXA; if(velXA < 0) minXA += velXA; if(velYA >= 0) maxYA += velYA; if(velYA < 0) minYA += velYA; pp = coB->getPhysicalProperties(); bv = coB->getBoundingVolume(); float widthB = bv->getWidth(); float heightB = bv->getHeight(); float xB = pp->getX() + bv->getX(); float yB = pp->getY() + bv->getY(); float velXB = pp->getVelocityX(); float velYB = pp->getVelocityY(); float minXB = xB-(widthB/2); float maxXB = xB+(widthB/2); float minYB = yB-(heightB/2); float maxYB = yB+(heightB/2); if(velXB >= 0) maxXB += velXB; if(velXB < 0) minXB += velXB; if(velYB >= 0) maxYB += velYB; if(velYB < 0) minYB += velYB; if( !(maxXB < minXA || minXB > maxXA || maxYB < minYA || minYB > maxYA)) return true; return false; }
void BoundingVolume::transform(const BoundingVolume &in_volume, glm::mat4 matrix) { // Make sure the bounding volume itself is cleared before transformation reset(); glm::vec4 min_corner(in_volume.min_corner(), 1.0f); glm::vec4 max_corner(in_volume.max_corner(), 1.0f); glm::vec4 transformed_min_corner = matrix * min_corner; glm::vec4 transformed_max_corner = matrix * max_corner; glm::vec3 transformed_min(transformed_min_corner.x, transformed_min_corner.y, transformed_min_corner.z); glm::vec3 transformed_max(transformed_max_corner.x, transformed_max_corner.y, transformed_max_corner.z); // expand with the new corners expand(transformed_min); expand(transformed_max); }
/* clone - this method makes another BackAndForthBot object, but does not completely initialize it with similar data to this. Most of the object, like velocity and position, are left uninitialized. */ Bot* BackAndForthBot::clone() { BackAndForthBot *botClone = new BackAndForthBot(); PhysicalProperties* pp = this->getPhysicalProperties(); PhysicalProperties* bp = botClone->getPhysicalProperties(); BoundingVolume* pV = this->getBoundingVolume(); BoundingVolume* bV = botClone->getBoundingVolume(); botClone->setEnemy(enemy); botClone->setItem(item); botClone->setPortal(portal); botClone->setSpriteType(this->getSpriteType()); botClone->setAlpha(this->getAlpha()); botClone->setDead(false); bp->setCollidable(pp->isCollidable()); bp->setGravAffected(pp->isGravAffected()); bV->setHeight(pV->getHeight()); bV->setWidth(pV->getWidth()); bV->setX(pV->getX()); bV->setY(pV->getY()); return botClone; }
/* * Uses the technique described here: * http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ */ void BoundingVolume::transform(const BoundingVolume &in_volume, glm::mat4 matrix) { // Make sure the bounding volume itself is cleared before transformation reset(); glm::vec3 center = (in_volume.min_corner() + in_volume.max_corner()) / 2.0f; glm::vec3 extent = (in_volume.max_corner() - in_volume.min_corner()) / 2.0f; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { scratch_abs_matrix[i, j] = abs(matrix[i, j]); } } glm::vec4 new_center = matrix * glm::vec4(center, 1.0f); glm::vec4 new_extent = scratch_abs_matrix * glm::vec4(extent, 0.0f); glm::vec4 bb_min = new_center - new_extent; glm::vec4 bb_max = new_center + new_extent; expand(glm::vec3(bb_min.x, bb_min.y, bb_min.z)); expand(glm::vec3(bb_max.x, bb_max.y, bb_max.z)); }
/*! * TODO: Implement correct/faster collision detection methods for * collisions between different types of bounding volumes. */ bool BoundingSphere::collidesWith(const BoundingVolume& other) const { if (other.getVolumeType() == BV_TYPE_SPHERE) { const BoundingSphere& otherSphere = (const BoundingSphere&) other; real distance = (getCenterVector() - otherSphere.getCenterVector()).dotProduct(); real radii = (mRadius + otherSphere.getRadius()) * (mRadius + otherSphere.getRadius()); //std::cout << "2. Distanz : " << distance << " 2. radius: " << radii << std::endl; if (distance > radii) { return 0; } else { //std::cout << "Kollision" << std::endl; return 1; } } else { Aabb thisAabb(getSurroundingAabbMin(), getSurroundingAabbMax()); return thisAabb.collidesWith( Aabb(other.getSurroundingAabbMin(), other.getSurroundingAabbMax())); } }
/*! * \overload * * This method creates a new BoundingVolume as a copy of \p copy. */ BoundingVolume* BoundingVolume::createBoundingVolume(World* world, const BoundingVolume* copy, BvhNode* parent) { if (!copy) { return createBoundingVolume(world, parent); } if (copy->getVolumeType() != getCreateRigidBoundingVolumeType(world)) { std::stringstream errormessage; errormessage << "ERROR: requested a copy of BV type " << copy->getVolumeType() << ", but expected type " << getCreateRigidBoundingVolumeType(world) << std::endl; throw TypeMismatchException(errormessage.str()); } BoundingVolume* bv = 0; switch (getCreateRigidBoundingVolumeType(world)) { case BV_TYPE_AABB: bv = new Aabb(*static_cast<const Aabb*>(copy)); break; case BV_TYPE_KDOP: bv = new Kdop(*static_cast<const Kdop*>(copy)); break; case BV_TYPE_SPHERE: bv = new BoundingSphere(*static_cast<const BoundingSphere*>(copy)); break; case BV_TYPE_OBB: bv = new Obb(*static_cast<const Obb*>(copy)); break; default: // TODO: exception!! std::cerr << dc_funcinfo << "FATAL ERROR: bounding volume type " << getCreateRigidBoundingVolumeType(world) << " not supported" << std::endl; exit(1); return 0; } bv->setHierarchyNode(parent); return bv; }
bool EDBVH::Collide(const BoundingVolume& boundingVolume, unsigned int& triIndex, EDCollision::Contact* contact) { Aabb bvAabb = boundingVolume.GetAabb(); EDCollision::Contact newContact; newContact.numPoints = 0; newContact.PenetrationDepth = -FLT_MAX; BVtoBVH( boundingVolume, bvAabb, rootPtr, this, newContact, triIndex ); if( newContact.PenetrationDepth > 0.0f ) { if( contact ) *contact = newContact; return true; } return false; }
void Physics::collideTestWithTiles(CollidableObject *c,TiledLayer *tL, list<Collision*> *collisions) { BoundingVolume *bv = c->getBoundingVolume(); float toRight= bv->getWidth()/2; float toBottom = bv->getHeight()/2; PhysicalProperties *pp = c->getPhysicalProperties(); float x = pp->getX()+bv->getX(); float y = pp->getY()+bv->getY(); float xVel = pp->getVelocityX(); float yVel = pp->getVelocityY(); float minX = x - toRight; float maxX = x + toRight; float minY = y - toBottom; float maxY = y + toBottom; if(xVel > 0) maxX += xVel; else minX += xVel; if(yVel > 0) maxY += yVel; else minY += yVel; int tW = tL->getTileWidth(); int tH = tL->getTileHeight(); int firstCol = minX/tW; int lastCol = maxX/tW; int firstRow = minY/tH; int lastRow = maxY/tH; if(firstCol < 0) firstCol = 0; if(firstRow < 0) firstRow = 0; if(lastCol >= tL->getColumns()) lastCol = tL->getColumns() - 1; if(lastRow >= tL->getRows()) lastRow = tL->getRows() - 1; for(int i = firstRow; i <= lastRow; i++) { for(int j = firstCol; j <= lastCol; j++) { Tile* current = tL->getTile(i,j); if(current->collidable == true) { if( !( (i+1)*tH < minY || i*tH > maxY || (j+1)*tW < minX || j*tW > maxX) ) { CollidableObject* tileCO = coStack[coStackCounter]; coStackCounter --; BoundingVolume *bv = tileCO->getBoundingVolume(); bv->setWidth(tW); bv->setHeight(tH); bv->setX(tW/2); bv->setY(tW/2); pp = tileCO->getPhysicalProperties(); pp->setPosition(j*tW,i*tH); /* Collision* currentCollision = collisionStack.top(); collisionStack.pop();*/ Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(c); currentCollision->setCO2(tileCO); currentCollision->calculateTimes(); collisions->push_back(currentCollision); } } } } }
//---------------------------------------------------------------------------- Bool RenderText::Append(const Char* pText, Float x, Float y) { if (!pText) { return true; } VertexBuffer* pVertexBuffer = GetMesh()->GetVertexBuffer(); WIRE_ASSERT(pVertexBuffer && pVertexBuffer->GetAttributes().HasTCoord()); const UInt offset = GetMesh()->GetIndexCount()/6; const UInt maxLength = pVertexBuffer->GetQuantity() / 4; UInt indexCount = 0; BoundingVolume* pModelBound = GetMesh()->GetModelBound(); WIRE_ASSERT(pModelBound); Vector2F min(System::MAX_FLOAT, System::MAX_FLOAT); Vector2F max(System::MIN_FLOAT, System::MIN_FLOAT); Float radius = pModelBound->GetRadius(); Vector3F center3 = pModelBound->GetCenter(); if (radius != 0) { min = Vector2F(center3.X() - radius, center3.Y() - radius); max = Vector2F(center3.X() + radius, center3.Y() + radius); } for (UInt j = 0; pText[j]; j++) { if ((offset+indexCount) >= maxLength) { break; } UInt c = static_cast<UInt>(pText[j]); if (c == ' ') { x+= mWhitespaceWidth; continue; } if (c >= mCharSizes.GetQuantity()) { return false; } UInt i = (indexCount + offset) * 4; Float cWidth = mCharSizes[c].X(); Float cHeight = mCharSizes[c].Y(); Float cStride = mCharSizes[c].Z(); if ((x+cStride) >= mLineWidth || c == '\n') { x = 0.0F; y -= mFontHeight; if (c == '\n') { continue; } } Float cy = y - mCharSizes[c].W(); const Float x1 = x + cWidth; const Float cy1 = cy + cHeight; min.X() = min.X() > x ? x : min.X(); max.X() = max.X() < x1 ? x1 : max.X(); min.Y() = min.Y() > cy1 ? cy : min.Y(); max.Y() = max.Y() < cy1 ? cy1 : max.Y(); pVertexBuffer->Position3(i) = Vector3F(x, cy1, 0); pVertexBuffer->Color4(i) = mColor; pVertexBuffer->Position3(i+1) = Vector3F(x1, cy1, 0); pVertexBuffer->Color4(i+1) = mColor; pVertexBuffer->Position3(i+2) = Vector3F(x1, cy, 0); pVertexBuffer->Color4(i+2) = mColor; pVertexBuffer->Position3(i+3) = Vector3F(x, cy, 0); pVertexBuffer->Color4(i+3) = mColor; UInt c4 = c*4; pVertexBuffer->TCoord2(i) = mUvs[c4]; pVertexBuffer->TCoord2(i+1) = mUvs[c4+1]; pVertexBuffer->TCoord2(i+2) = mUvs[c4+2]; pVertexBuffer->TCoord2(i+3) = mUvs[c4+3]; x+= cStride; indexCount++; } GetMesh()->SetIndexCount(GetMesh()->GetIndexCount() + indexCount*6); mIsPdrBufferOutOfDate = true; Vector2F center((max.X()+min.X()) * 0.5F, (max.Y()+min.Y()) * 0.5F); pModelBound->SetCenter(Vector3F(center.X(), center.Y(), 0)); pModelBound->SetRadius((center - min).Length()); mPenX = x; mPenY = y; return true; }
/* * expand the volume by the incoming volume */ void BoundingVolume::expand(const BoundingVolume &volume) { expand(volume.min_corner()); expand(volume.max_corner()); }
Plane findPlane(Axis a, BoundingVolume const &bv) { int off{ 0 }; int smallest{ std::numeric_limits<int>::max() }; Vec3 min{ bv.min() }; Vec3 max{ bv.min() + bv.extent() }; // move candidate plane along axis switch (a) { case Axis::X: { svt::accum_delta next_offset(min.x, svt::delta.x); int pp{ next_offset() }; while (pp < max.x) { int diff{ diffSides( min, { min.x+pp, max.y, max.z }, { min.x+pp, min.y, min.z }, max ) }; std::cout << "X pp: " << pp << " diff: " << diff << "\n-----\n" ; //TODO: handle diff==smallest separately if (diff <= smallest) { smallest = diff; off = pp; } pp = next_offset(); } //for return Plane{ { min.x + off, min.y, min.z }, { min.x + off, max.y, max.z } }; } case Axis::Y: { svt::accum_delta next_offset(min.y, svt::delta.y); int pp{ next_offset() }; while(pp < max.y) { int diff{ diffSides( min, { max.x, min.y+pp, max.z }, { min.x, min.y+pp, min.z }, max ) }; std::cout << "Y pp: " << pp << " diff: " << diff << "\n-----\n" ; //TODO: handle diff==smallest separately if (diff <= smallest) { smallest = diff; off = pp; } pp = next_offset(); } //for return Plane{ { min.x, min.y + off, min.z }, { max.x, min.y + off, max.z } }; } case Axis::Z: { svt::accum_delta next_offset(min.z, svt::delta.z); int pp{ next_offset() }; while (pp < max.z) { int diff{ diffSides( min, { max.x, max.y, min.z+pp }, { min.x, min.y, min.z+pp }, max ) }; std::cout << "Z pp: " << pp << " diff: " << diff << "\n-----\n" ; //TODO: handle diff==smallest separately if (diff <= smallest) { smallest = diff; off = pp; } pp = next_offset(); } //for return Plane{ { min.x, min.y, min.z + off }, { max.x, max.y, min.z + off } }; } default: break; } return Plane{ { -1,-1,-1 }, { -1,-1,-1 } }; // The most interesting case. }
void MeshSkin::computeBounds() { // Find the offset of the blend indices and blend weights within the mesh vertices int blendIndexOffset = -1; int blendWeightOffset = -1; for (unsigned int i = 0, count = _mesh->getVertexElementCount(); i < count; ++i) { const VertexElement& e = _mesh->getVertexElement(i); switch (e.usage) { case BLENDINDICES: blendIndexOffset = i; break; case BLENDWEIGHTS: blendWeightOffset = i; break; } } if (blendIndexOffset == -1 || blendWeightOffset == -1) { // Need blend indices and blend weights to calculate skinned bounding volume return; } LOG(2, "Computing bounds for skin of mesh: %s\n", _mesh->getId().c_str()); // Get the root joint if (_joints.size() == 0) return; Node* rootJoint = _joints[0]; Node* parent = rootJoint->getParent(); while (parent) { // Is this parent in the list of joints that form the skeleton? // If not, then it's simply a parent node to the root joint if (find(_joints.begin(), _joints.end(), parent) != _joints.end()) { rootJoint = parent; } parent = parent->getParent(); } // If the root joint has a parent node, temporarily detach it so that its transform is // not included in the bounding volume calculation below Node* rootJointParent = rootJoint->getParent(); if (rootJointParent) { rootJointParent->removeChild(rootJoint); } unsigned int jointCount = _joints.size(); unsigned int vertexCount = _mesh->getVertexCount(); LOG(3, " %u joints found.\n", jointCount); std::vector<AnimationChannel*> channels; std::vector<Node*> channelTargets; std::vector<Curve*> curves; std::vector<Vector3> vertices; _jointBounds.resize(jointCount); // Construct a list of all animation channels that target the joints affecting this mesh skin LOG(3, " Collecting animations...\n"); LOG(3, " 0%%\r"); for (unsigned int i = 0; i < jointCount; ++i) { Node* joint = _joints[i]; // Find all animations that target this joint Animations* animations = GPBFile::getInstance()->getAnimations(); for (unsigned int j = 0, animationCount = animations->getAnimationCount(); j < animationCount; ++j) { Animation* animation = animations->getAnimation(j); for (unsigned int k = 0, channelCount = animation->getAnimationChannelCount(); k < channelCount; ++k) { AnimationChannel* channel = animation->getAnimationChannel(k); if (channel->getTargetId() == joint->getId()) { if (find(channels.begin(), channels.end(), channel) == channels.end()) { channels.push_back(channel); channelTargets.push_back(joint); } } } } // Calculate the local bounding volume for this joint vertices.clear(); BoundingVolume jointBounds; jointBounds.min.set(FLT_MAX, FLT_MAX, FLT_MAX); jointBounds.max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (unsigned int j = 0; j < vertexCount; ++j) { const Vertex& v = _mesh->getVertex(j); if ((v.blendIndices.x == i && !ISZERO(v.blendWeights.x)) || (v.blendIndices.y == i && !ISZERO(v.blendWeights.y)) || (v.blendIndices.z == i && !ISZERO(v.blendWeights.z)) || (v.blendIndices.w == i && !ISZERO(v.blendWeights.w))) { vertices.push_back(v.position); // Update box min/max if (v.position.x < jointBounds.min.x) jointBounds.min.x = v.position.x; if (v.position.y < jointBounds.min.y) jointBounds.min.y = v.position.y; if (v.position.z < jointBounds.min.z) jointBounds.min.z = v.position.z; if (v.position.x > jointBounds.max.x) jointBounds.max.x = v.position.x; if (v.position.y > jointBounds.max.y) jointBounds.max.y = v.position.y; if (v.position.z > jointBounds.max.z) jointBounds.max.z = v.position.z; } } if (vertices.size() > 0) { // Compute center point Vector3::add(jointBounds.min, jointBounds.max, &jointBounds.center); jointBounds.center.scale(0.5f); // Compute radius for (unsigned int j = 0, jointVertexCount = vertices.size(); j < jointVertexCount; ++j) { float d = jointBounds.center.distanceSquared(vertices[j]); if (d > jointBounds.radius) jointBounds.radius = d; } jointBounds.radius = sqrt(jointBounds.radius); } _jointBounds[i] = jointBounds; LOG(3, " %d%%\r", (int)((float)(i+1) / (float)jointCount * 100.0f)); } LOG(3, "\n"); unsigned int channelCount = channels.size(); // Create a Curve for each animation channel float maxDuration = 0.0f; LOG(3, " Building animation curves...\n"); LOG(3, " 0%%\r"); for (unsigned int i = 0; i < channelCount; ++i) { AnimationChannel* channel = channels[i]; const std::vector<float>& keyTimes = channel->getKeyTimes(); unsigned int keyCount = keyTimes.size(); if (keyCount == 0) continue; // Create a curve for this animation channel Curve* curve = NULL; switch (channel->getTargetAttribute()) { case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE: curve = new Curve(keyCount, 10); curve->setQuaternionOffset(3); break; } if (curve == NULL) { // Unsupported/not implemented curve type continue; } // Copy key values into a temporary array unsigned int keyValuesCount = channel->getKeyValues().size(); float* keyValues = new float[keyValuesCount]; for (unsigned int j = 0; j < keyValuesCount; ++j) keyValues[j] = channel->getKeyValues()[j]; // Determine animation duration float startTime = keyTimes[0]; float duration = keyTimes[keyCount-1] - startTime; if (duration > maxDuration) maxDuration = duration; if (duration > 0.0f) { // Set curve points float* keyValuesPtr = keyValues; for (unsigned int j = 0; j < keyCount; ++j) { // Store time normalized, between 0-1 float t = (keyTimes[j] - startTime) / duration; // Set the curve point // TODO: Handle other interpolation types curve->setPoint(j, t, keyValuesPtr, gameplay::Curve::LINEAR); // Move to the next point on the curve keyValuesPtr += curve->getComponentCount(); } curves.push_back(curve); } delete[] keyValues; keyValues = NULL; LOG(3, " %d%%\r", (int)((float)(i+1) / (float)channelCount * 100.0f)); } LOG(3, "\n"); // Compute a total combined bounding volume for the MeshSkin that contains all possible // vertex positions for all animations targeting the skin. This rough approximation allows // us to store a volume that can be used for rough intersection tests (such as for visibility // determination) efficiently at runtime. // Backup existing node transforms so we can restore them when we are finished Matrix* oldTransforms = new Matrix[jointCount]; for (unsigned int i = 0; i < jointCount; ++i) { memcpy(oldTransforms[i].m, _joints[i]->getTransformMatrix().m, 16 * sizeof(float)); } float time = 0.0f; float srt[10]; Matrix temp; Matrix* jointTransforms = new Matrix[jointCount]; _mesh->bounds.min.set(FLT_MAX, FLT_MAX, FLT_MAX); _mesh->bounds.max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); _mesh->bounds.center.set(0, 0, 0); _mesh->bounds.radius = 0; Vector3 skinnedPos; Vector3 tempPos; LOG(3, " Evaluating joints...\n"); LOG(3, " 0%%\r"); BoundingVolume finalBounds; while (time <= maxDuration) { // Evaluate joint transforms at this time interval for (unsigned int i = 0, curveCount = curves.size(); i < curveCount; ++i) { Node* joint = channelTargets[i]; Curve* curve = curves[i]; // Evalulate the curve at this time to get the new value float tn = time / maxDuration; if (tn > 1.0f) tn = 1.0f; curve->evaluate(tn, srt); // Update the joint's local transform Matrix::createTranslation(srt[7], srt[8], srt[9], temp.m); temp.rotate(*((Quaternion*)&srt[3])); temp.scale(srt[0], srt[1], srt[2]); joint->setTransformMatrix(temp.m); } // Store the final matrix pallette of resovled world space joint matrices std::vector<Matrix>::const_iterator bindPoseItr = _bindPoses.begin(); for (unsigned int i = 0; i < jointCount; ++i, bindPoseItr++) { BoundingVolume bounds = _jointBounds[i]; if (ISZERO(bounds.radius)) continue; Matrix& m = jointTransforms[i]; Matrix::multiply(_joints[i]->getWorldMatrix().m, bindPoseItr->m, m.m); Matrix::multiply(m.m, _bindShape, m.m); // Get a world-space bounding volume for this joint bounds.transform(m); if (ISZERO(finalBounds.radius)) finalBounds = bounds; else finalBounds.merge(bounds); } // Increment time by 1/30th of second (~ 33 ms) if (time < maxDuration && (time + 33.0f) > maxDuration) time = maxDuration; else time += 33.0f; LOG(3, " %d%%\r", (int)(time / maxDuration * 100.0f)); } LOG(3, "\n"); // Update the bounding sphere for the mesh _mesh->bounds = finalBounds; // Restore original joint transforms for (unsigned int i = 0; i < jointCount; ++i) { _joints[i]->setTransformMatrix(oldTransforms[i].m); } // Cleanup for (unsigned int i = 0, curveCount = curves.size(); i < curveCount; ++i) { delete curves[i]; } delete[] oldTransforms; delete[] jointTransforms; // Restore removed joints if (rootJointParent) { rootJointParent->addChild(rootJoint); } }
int main(int argc, char* argv[]) { cout << "HELLO WORLD" << endl; //if (argc == 2) return -1; int currentArg = 1; ProgramSettings* settings = new ProgramSettings(); // take in arguements and settings while (currentArg != argc) { char* arg = argv[currentArg]; if (strcmp(arg, "--in") == 0) { settings->mesh = string(argv[++currentArg]); } else if (strcmp(arg, "--out") == 0) { cout << "FOUND OUTPUT:: " << endl; settings->outputMesh = string(argv[++currentArg]); } else if (strcmp(arg, "--config") == 0) { settings->config = string(argv[++currentArg]); cout << "FOUND FORCE FILE" << endl; } else if (strcmp(arg, "--force") == 0) { settings->outputForce = string(argv[++currentArg]); } else if (strcmp(arg, "--corner") == 0) { settings->corner = atoi(argv[++currentArg]); } else if (strcmp(arg, "--cubeAlign") == 0) { settings->needsAlignment = true; settings->cubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--topCubeAlign") == 0) { settings->needsAlignment = true; settings->topCubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--botCubeAlign") == 0) { settings->needsAlignment = true; settings->botCubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--rightCubeAlign") == 0) { settings->needsAlignment = true; settings->rightCubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--leftCubeAlign") == 0) { settings->needsAlignment = true; settings->leftCubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--frontCubeAlign") == 0) { settings->needsAlignment = true; settings->frontCubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--backCubeAlign") == 0) { settings->needsAlignment = true; settings->backCubeAlign = true; settings->depth = atof(argv[++currentArg]); } else if (strcmp(arg, "--maxForce") == 0) { settings->needsForce = true; cout << "FOUND MAX FORCE" << endl; settings->maxForce = atof(argv[++currentArg]); } else if (strcmp(arg, "--constant") == 0) { settings->needsForce = true; settings->constantForce = true; settings->maxForce = atof(argv[++currentArg]); } else if (strcmp(arg, "--impulse") == 0) { settings->needsForce = true; settings->impulseForce = true; settings->maxForce = atof(argv[++currentArg]); } else if (strcmp(arg, "--bezierFile") == 0) { settings->bezierForce = true; settings->bezierForceFile = string(argv[++currentArg]); } else if (strcmp(arg, "--topCubeForce") == 0) { settings->topCubeForce = true; settings->forceDepth = atof(argv[++currentArg]); } else if (strcmp(arg, "--botCubeForce") == 0) { settings->botCubeForce = true; settings->forceDepth = atof(argv[++currentArg]); } else if (strcmp(arg, "--rightCubeForce") == 0) { settings->rightCubeForce = true; settings->forceDepth = atof(argv[++currentArg]); } else if (strcmp(arg, "--leftCubeForce") == 0) { settings->leftCubeForce = true; settings->forceDepth = atof(argv[++currentArg]); } else if (strcmp(arg, "--frontCubeForce") == 0) { settings->frontCubeForce = true; settings->forceDepth = atof(argv[++currentArg]); } else if (strcmp(arg, "--backCubeForce") == 0) { settings->backCubeForce = true; settings->forceDepth = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainMinX") == 0) { settings->domainForce = true; settings->domainX[0] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainMaxX") == 0) { settings->domainForce = true; settings->domainX[1] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainMinY") == 0) { settings->domainForce = true; settings->domainY[0] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainMaxY") == 0) { settings->domainForce = true; settings->domainY[1] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainMinZ") == 0) { settings->domainForce = true; settings->domainZ[0] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainMaxZ") == 0) { settings->domainForce = true; settings->domainZ[1] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainBezier") == 0) { settings->domainBezier = true; } else if (strcmp(arg, "--domainDirX") == 0) { settings->domainForce = true; settings->direction[0] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainDirY") == 0) { settings->domainForce = true; settings->direction[1] = atof(argv[++currentArg]); } else if (strcmp(arg, "--domainDirZ") == 0) { settings->domainForce = true; settings->direction[2] = atof(argv[++currentArg]); } currentArg++; } // stages of the program // read in all the verts and faces cout << "Making Mesh" << endl; Mesh* mesh = new Mesh(settings->mesh); cout << "Made Mesh" << endl; // calculate the bounding shape based on the verts BoundingVolume* volume = 0x0; //if (settings->needsAlignment) { if (true) { // initialize bounding volume //if (settings->cubeAlign) volume = mesh->createCubeBound(settings->depth); //else if (settings->topCubeAlign) volume = mesh->createTopBound(settings->depth); //else if (settings->botCubeAlign) volume = mesh->createBotBound(settings->depth); //else if (settings->rightCubeAlign) volume = mesh->createRightBound(settings->depth); //else if (settings->leftCubeAlign) volume = mesh->createLeftBound(settings->depth); //else if (settings->frontCubeAlign) volume = mesh->createFrontBound(settings->depth); //else if (settings->backCubeAlign) volume = mesh->createBackBound(settings->depth); cout << "Creating Fixed Volume" << endl; volume = mesh->createLeftBound(0.0); cout << "Created Fixed Volume" << endl; // translate the object to the origin //vec3 newOrigin = volume->getNewOrigin(settings->corner); cout << "Getting Origin" << endl; dvec3 newOrigin = volume->getNewOrigin(1); cout << "ORIGIN:: " << newOrigin[0] << " " << newOrigin[1] << " " << newOrigin[2] << endl; //mesh->translate(-newOrigin[0], -newOrigin[1], -newOrigin[2]); mesh->translate(-mesh->xExtremes[0], -mesh->yExtremes[1], -mesh->zExtremes[1]); cout << "Making Fixed" << endl; volume->makeFixed(); } // calculate the force bounds and calculate all forces within it BoundingVolume* forceVolume = 0x0; //if (settings->needsForce cout << "Calculating Force Volume" << endl; if (true) { // initialize force bounding volume //if (settings->topCubeForce) forceVolume = mesh->createTopBound(settings->forceDepth); //else if (settings->botCubeForce) forceVolume = mesh->createBotBound(settings->forceDepth); //else if (settings->rightCubeForce) forceVolume = mesh->createRightBound(settings->forceDepth); //else if (settings->leftCubeForce) forceVolume = mesh->createLeftBound(settings->forceDepth); //else if (settings->frontCubeForce) forceVolume = mesh->createFrontBound(settings->forceDepth); //else if (settings->backCubeForce) forceVolume = mesh->createBackBound(settings->forceDepth); cout << "FIXED BOUNDS :: " << volume->verts.size() << endl; cout << "Creating Line Bound" << endl; cout << "MESH XBNDS :: " << mesh->xBnds()[0] << " " << mesh->xBnds()[1] << endl; cout << "MESH YBNDS :: " << mesh->yBnds()[0] << " " << mesh->yBnds()[1] << endl; cout << "MESH ZBNDS :: " << mesh->zBnds()[0] << " " << mesh->zBnds()[1] << endl; forceVolume = mesh->createLineBound(mesh->xBnds()[1], 0.0, mesh->zBnds()[1], false, true, false); // distribute force per vert in volume cout << "Distributing Max Force" << endl; cout << "MAX FORCE :: " << settings->maxForce << endl; forceVolume->distributeForce(settings->maxForce); } // print all verts with forces into the data file cout << "Writing All Files" << endl; mesh->writeToFile(settings); cout << "Cleaning Up" << endl; // clean up if (forceVolume) delete forceVolume; if (volume) delete volume; delete mesh; delete settings; }
void Physics::resolveCollision(Game* game, Collision* currentCollision) { CollidableObject* co1 = currentCollision->getCO1(); CollidableObject* co2 = currentCollision->getCO2(); PhysicalProperties* pp; BoundingVolume* bv; AnimatedSprite* player = game->getGSM()->getSpriteManager()->getPlayer(); if(co2->isStaticObject() == true) { pp = co2->getPhysicalProperties(); bv = co2->getBoundingVolume(); float tX = pp->getX(); float tY = pp->getY(); float tXR = tX + bv->getWidth(); float tYB = tY + bv->getHeight(); pp = co1->getPhysicalProperties(); bv = co1->getBoundingVolume(); float x = pp->getX() + bv->getX() - (bv->getWidth()/2); float y = pp->getY() + bv->getY() - (bv->getHeight()/2); float xR = x+bv->getWidth(); float yB = y+bv->getHeight(); //pp->setVelocity(0, 0); /*if(x < tX) pp->setX(pp->getX() - 0.1); if(x > tX) pp->setX(pp->getX() + 0.1);*/ if(x >= tXR) { pp->setX(pp->getX() + 0.1); pp->setVelocity(0, pp->getVelocityY()); } if(xR <= tX) { pp->setX(pp->getX() - 0.1); pp->setVelocity(0, pp->getVelocityY()); } if(y >= tYB) { pp->setY(pp->getY() + 0.1); pp->setVelocity(pp->getVelocityX(), 0); } if(yB <= tY) { pp->setY(pp->getY() - 0.1); if(co1 == player) { pp->setJumped(false); pp->setDoubleJumped(false); pp->setStunned(false); } pp->setVelocity(pp->getVelocityX(), 0); } //if(currentCollision->getTOC() == currentCollision->getSYC()) //{ // /*if(pp->getVelocityY() < 0) // { // pp->setY(pp->getY() + 0.1); // } // else // { // pp->setY(pp->getY() - 0.1); // if(co1 == player) // { // pp->setJumped(false);s // pp->setDoubleJumped(false); // if(player->getCurrentState().compare(L"JUMP_STATE") == 0 // || player->getCurrentState().compare(L"JUMPL_STATE") == 0) // { // player->setCurrentState(L"IDLE_STATE"); // } // } // }*/ // if(y < tY) // { // pp->setY(pp->getY() - 0.1); // if(co1 == player) // { // pp->setJumped(false); // pp->setDoubleJumped(false); // /*if(player->getCurrentState().compare(L"JUMP_STATE") == 0 // || player->getCurrentState().compare(L"JUMPL_STATE") == 0) // { // player->setCurrentState(L"IDLE_STATE"); // }*/ // } // } // if(y > tY) // { // pp->setY(pp->getY() + 0.1); // // } // pp->setVelocity(pp->getVelocityX(), 0); // // //} //else if(currentCollision->getTOC() == currentCollision->getSXC()) //{ // /*if(pp->getVelocityX() < 0) // { // pp->setX(pp->getX() + 0.1); // } // else // { // pp->setX(pp->getX() - 0.1); // }*/ // /*if(x < tX) // pp->setX(pp->getX() - 0.1); // if(x > tX) // pp->setX(pp->getX() + 0.1);*/ // pp->setVelocity(0, pp->getVelocityY()); //} //else //{ // /*if(pp->getVelocityY() < 0) // pp->setY(pp->getY() + 0.1); // else // pp->setY(pp->getY() - 0.1); // if(pp->getVelocityX() < 0) // pp->setX(pp->getX() + 0.1); // else // pp->setX(pp->getX() - 0.1);*/ // pp->setVelocity(0,0); //} } else { pp = co1->getPhysicalProperties(); bv = co1->getBoundingVolume(); float x = pp->getX()+ bv->getX() - (bv->getWidth()/2); float y = pp->getY()+ bv->getY() - (bv->getHeight()/2); float xR = x + bv->getWidth(); float yB = y + bv->getHeight(); PhysicalProperties* p2 = co2->getPhysicalProperties(); bv = co2->getBoundingVolume(); float tX = p2->getX() + bv->getX() - (bv->getWidth()/2); float tY = p2->getY() + bv->getY() - (bv->getHeight()/2); float tXR = tX+bv->getWidth(); float tYB = tY+bv->getHeight(); //pp->setVelocity(0, 0); if(x >= tXR) { if(co1->isMobile()) pp->setX(pp->getX() + 0.1); if(co2->isMobile()) p2->setX(p2->getX() - 0.1); } if(xR <= tX) { if(co1->isMobile()) pp->setX(pp->getX() - 0.1); if(co2->isMobile()) p2->setX(p2->getX() + 0.1); } if(y >= tYB) { if(co1->isMobile()) pp->setY(pp->getY() + 0.1); if(co2->isMobile()) p2->setY(p2->getY() - 0.1); } if(yB <= tY) { if(co1->isMobile()) pp->setY(pp->getY() - 0.1); if(co2->isMobile()) p2->setY(p2->getY() + 0.1); } } }