int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) { (void)fixedTimeStep; (void)maxSubSteps; ///apply gravity, predict motion predictUnconstraintMotion(timeStep); btDispatcherInfo& dispatchInfo = getDispatchInfo(); dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; dispatchInfo.m_debugDraw = getDebugDrawer(); ///perform collision detection performDiscreteCollisionDetection(); ///solve contact constraints int numManifolds = m_dispatcher1->getNumManifolds(); if (numManifolds) { btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer(); btContactSolverInfo infoGlobal; infoGlobal.m_timeStep = timeStep; m_constraintSolver->prepareSolve(0,numManifolds); m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_dispatcher1); m_constraintSolver->allSolved(infoGlobal,m_debugDrawer); } ///integrate transforms integrateTransforms(timeStep); updateAabbs(); synchronizeMotionStates(); clearForces(); return 1; }
void Particle::integrate(fseconds duration) { // don't move objects that have "infinite mass." if (invMass <= 0.0f) { return; } //update velocity using Verlet vel = vel + 1.0f/2.0f*acc*duration.count(); // update position using Velocity Verlet pos = pos + vel * duration.count(); vec3 resultantAcc = (pos+duration.count())-(2.0f*pos+pos)-(duration.count()); // update velocity using Velocity Verlet vel = vel + 1.0f/2.0f*resultantAcc*duration.count(); // incorporate damping vel = vel * damping; clearForces(); }
void Particle::integrate(fseconds duration) { // don't move objects that have "infinite mass." if (invMass <= 0.0f) { return; } // update position using Euler integration pos = pos + duration.count() * vel; vec3 resultantAcc = acc; resultantAcc = resultantAcc + (invMass * accumulatedForces); // update velocity using Euler integration vel = vel + duration.count() * resultantAcc; // incorporate damping vel = vel * damping; clearForces(); }
void Solver::Solve(double dt) { for (int i = 0; i < ray.size(); i++) ray[i]->setAABB(); if (applyg) applyg(body); else applyG(); BPT.Start(); bp.sort(); BPT.End(); NPT.Start(); checkCol(); NPT.End(); applyForces(dt); SLT.Start(); solveVelocities(dt); SLT.End(); MVT.Start(); solvePositions(dt); MVT.End(); clearForces(); }
int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) { startProfiling(timeStep); BT_PROFILE("stepSimulation"); int numSimulationSubSteps = 0; if (maxSubSteps) { //fixed timestep with interpolation m_localTime += timeStep; if (m_localTime >= fixedTimeStep) { numSimulationSubSteps = int( m_localTime / fixedTimeStep); m_localTime -= numSimulationSubSteps * fixedTimeStep; } } else { //variable timestep fixedTimeStep = timeStep; m_localTime = timeStep; if (btFuzzyZero(timeStep)) { numSimulationSubSteps = 0; maxSubSteps = 0; } else { numSimulationSubSteps = 1; maxSubSteps = 1; } } //process some debugging flags if (getDebugDrawer()) { btIDebugDraw* debugDrawer = getDebugDrawer (); gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; } if (numSimulationSubSteps) { //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; saveKinematicState(fixedTimeStep*clampedSimulationSteps); applyGravity(); for (int i=0;i<clampedSimulationSteps;i++) { internalSingleStepSimulation(fixedTimeStep); synchronizeMotionStates(); } } else { synchronizeMotionStates(); } clearForces(); #ifndef BT_NO_PROFILE CProfileManager::Increment_Frame_Counter(); #endif //BT_NO_PROFILE return numSimulationSubSteps; }
int b3GpuDynamicsWorld::stepSimulation( btScalar timeStepUnused, int maxSubStepsUnused, btScalar fixedTimeStep) { ///Don't use more than 1 simulation step, it destroys the performance having to copy the data between CPU and GPU multiple times per frame ///Please use the CPU version in btDiscreteDynamicsWorld if you don't like this #ifndef BT_NO_PROFILE CProfileManager::Reset(); #endif //BT_NO_PROFILE BT_PROFILE("stepSimulation"); { BT_PROFILE("sync constraints CPU"); //todo: determine what data has changed, or perform copy on GPU? for (int i=0;i<m_constraints.size();i++) { btTypedConstraint* constraint = m_constraints[i]; b3TypedConstraint* c = (b3TypedConstraint*) constraint->getUserConstraintPtr(); if (c) { switch (constraint->getConstraintType()) { case POINT2POINT_CONSTRAINT_TYPE: { btPoint2PointConstraint* p2 = (btPoint2PointConstraint*) constraint; b3Point2PointConstraint* p3 = (b3Point2PointConstraint*) c; p3->setPivotA((const b3Vector3&)p2->getPivotInA()); p3->setPivotB((const b3Vector3&)p2->getPivotInB()); p3->m_setting.m_damping = p2->m_setting.m_damping; p3->m_setting.m_impulseClamp = p2->m_setting.m_impulseClamp; p3->m_setting.m_tau = p2->m_setting.m_tau; break; }; case D6_CONSTRAINT_TYPE: { btGeneric6DofConstraint* dof2 = (btGeneric6DofConstraint*) constraint; b3Generic6DofConstraint* dof3 = (b3Generic6DofConstraint*) c; const b3RigidBodyCL* bodiesCL = m_np->getBodiesCpu(); b3Transform frameInA = (b3Transform&) dof2->getFrameOffsetA(); b3Transform frameInB = (b3Transform&) dof2->getFrameOffsetB(); dof3->setFrames(frameInA,frameInB,bodiesCL); break; } default: { } }; } } } // detect any change (very simple) { BT_PROFILE("body update revision detection (CPU)"); #ifdef BT_USE_BODY_UPDATE_REVISION b3Assert(m_bodyUpdateRevisions.size() == m_collisionObjects.size()); b3Assert(m_np->getNumRigidBodies() == m_bodyUpdateRevisions.size()); #endif //BT_USE_BODY_UPDATE_REVISION for (int i=0;i<this->m_collisionObjects.size();i++) { if (i>=m_np->getNumRigidBodies()) { b3Error("bodiesCL out-of-range\n"); continue; } #ifdef BT_USE_BODY_UPDATE_REVISION if (m_bodyUpdateRevisions[i] != m_collisionObjects[i]->getUpdateRevisionInternal()) #endif//BT_USE_BODY_UPDATE_REVISION { m_cpuGpuSync = true; #ifdef BT_USE_BODY_UPDATE_REVISION m_bodyUpdateRevisions[i] = m_collisionObjects[i]->getUpdateRevisionInternal(); #endif btRigidBody* body = btRigidBody::upcast(m_collisionObjects[i]); if (body) { b3Vector3 pos = (const b3Vector3&)m_collisionObjects[i]->getWorldTransform().getOrigin(); btQuaternion orn2 = m_collisionObjects[i]->getWorldTransform().getRotation(); b3Quaternion orn(orn2[0],orn2[1],orn2[2],orn2[3]); body->integrateVelocities(fixedTimeStep); m_np->setObjectTransformCpu(&pos[0],&orn[0],i); b3Vector3 linVel = (const b3Vector3&)body->getLinearVelocity(); b3Vector3 angVel = (const b3Vector3&)body->getAngularVelocity(); m_np->setObjectVelocityCpu(&linVel[0],&angVel[0],i); } } } } if (m_cpuGpuSync) { BT_PROFILE("cpuGpuSync"); m_cpuGpuSync = false; m_np->writeAllBodiesToGpu(); m_bp->writeAabbsToGpu(); m_rigidBodyPipeline->writeAllInstancesToGpu(); } //internalSingleStepSimulation(fixedTimeStep); // dispatch preTick callback if(0 != m_internalPreTickCallback) { BT_PROFILE("internalPreTickCallback"); (*m_internalPreTickCallback)(this, fixedTimeStep); } { BT_PROFILE("m_rigidBodyPipeline->stepSimulation"); m_rigidBodyPipeline->stepSimulation(fixedTimeStep); } { BT_PROFILE("readbackBodiesToCpu"); //now copy info back to rigid bodies.... m_np->readbackAllBodiesToCpu(); } { BT_PROFILE("scatter transforms into rigidbody (CPU)"); const b3RigidBodyCL* bodiesCL = m_np->getBodiesCpu(); for (int i=0;i<this->m_collisionObjects.size();i++) { btVector3 pos; btQuaternion orn; if (m_np->getObjectTransformFromCpu(&pos[0],&orn[0],i)) { btTransform newTrans; newTrans.setOrigin(pos); newTrans.setRotation(orn); btCollisionObject* colObj = this->m_collisionObjects[i]; colObj->setWorldTransform(newTrans); btRigidBody* body = btRigidBody::upcast(m_collisionObjects[i]); if (body) { body->setLinearVelocity((btVector3&)bodiesCL[i].m_linVel); body->setAngularVelocity((btVector3&)bodiesCL[i].m_angVel); } } #ifdef BT_USE_BODY_UPDATE_REVISION //ignore this revision update m_bodyUpdateRevisions[i] = m_collisionObjects[i]->getUpdateRevisionInternal(); #endif //BT_USE_BODY_UPDATE_REVISION } { BT_PROFILE("synchronizeMotionStates"); synchronizeMotionStates(); } } clearForces(); #ifndef B3_NO_PROFILE CProfileManager::Increment_Frame_Counter(); #endif //B3_NO_PROFILE return 1; }
MainWindow::MainWindow(QDesktopWidget * d):QMainWindow() { this->setMinimumSize(d->availableGeometry().width()/1.15, d->availableGeometry().height()/1.25); this->setDockNestingEnabled(false); this->setDockOptions(NULL); this->setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); this->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); this->setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); this->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); databackend=new DataBackend(); databackend->setDataInserter(new ChangeFactory(databackend)); databrowser=new DataBrowser(databackend,d); dataeditor=new DataEditor(databackend,d); QObject::connect(databrowser,SIGNAL(editObject(QString)),dataeditor,SLOT(loadObject(QString))); QObject::connect(databrowser,SIGNAL(editForce(QString)),dataeditor,SLOT(loadForce(QString))); QObject::connect(databrowser,SIGNAL(editMacro(QString)),dataeditor,SLOT(loadMacro(QString))); QObject::connect(databrowser,SIGNAL(editConstant(QString)),dataeditor,SLOT(loadConstant(QString))); QObject::connect(databrowser,SIGNAL(deleteObject(QString)),dataeditor,SLOT(loadBlank())); QObject::connect(databrowser,SIGNAL(deleteForce(QString)),dataeditor,SLOT(loadBlank())); QObject::connect(databrowser,SIGNAL(deleteMacro(QString)),dataeditor,SLOT(loadBlank())); QObject::connect(databrowser,SIGNAL(deleteConstant(QString)),dataeditor,SLOT(loadBlank())); simcontrol=new SimulationControl(databackend); openglpane=new GLDrawPane(databackend,d); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), openglpane, SLOT(updateGL())); connect(qApp, SIGNAL(lastWindowClosed()),timer,SLOT(stop())); timer -> start(15); this->setCentralWidget(openglpane); this->addDockWidget(Qt::RightDockWidgetArea, databrowser); this->addDockWidget(Qt::RightDockWidgetArea, dataeditor); this->addDockWidget(Qt::BottomDockWidgetArea, simcontrol); QMenu * fileMenu = this->menuBar()->addMenu(tr("File")); QMenu * newMenu=fileMenu->addMenu("New Project"); newMenu->addAction("Blank Project",databackend,SLOT(newFromBlank()),QKeySequence("Ctrl+N")); newMenu->addAction("From Default",databackend,SLOT(newFromDefault()),QKeySequence("Ctrl+Shift+N")); fileMenu->addAction("Open Project",databackend,SLOT(load()),QKeySequence("Ctrl+O")); fileMenu->addAction("Save Project",databackend,SLOT(save()),QKeySequence("Ctrl+S")); fileMenu->addAction("Save Project As",databackend,SLOT(saveAs()),QKeySequence("Ctrl+Shift+S")); fileMenu->addAction("Exit",databackend, SLOT(quit())); QMenu * editMenu = this->menuBar()->addMenu(tr("Edit")); QAction * undo=databackend->getUndoStack()->createUndoAction(this); undo->setShortcut(QKeySequence(QKeySequence::Undo)); editMenu->addAction(undo); QAction * redo=databackend->getUndoStack()->createRedoAction(this); redo->setShortcut(QKeySequence(QKeySequence::Redo)); editMenu->addAction(redo); QMenu * viewMenu = this->menuBar()->addMenu(tr("View")); QMenu * cameraMenu=viewMenu->addMenu("Camera Presets"); cameraMenu->addAction("Isometric",this,SLOT(view_setIsometric())); cameraMenu->addAction("View XY Plane",this,SLOT(view_setXY())); cameraMenu->addAction("View XZ Plane",this,SLOT(view_setXZ())); cameraMenu->addAction("View YZ Plane",this,SLOT(view_setYZ())); QMenu * zoomMenu=viewMenu->addMenu("Zoom"); QActionGroup * zoomGroup=new QActionGroup(NULL); zoomGroup->addAction(zoomMenu->addAction("10%",this,SLOT(view_zoom10())))->setCheckable(true); zoomGroup->addAction(zoomMenu->addAction("50%",this,SLOT(view_zoom50())))->setCheckable(true); zoomGroup->addAction(zoomMenu->addAction("100%",this,SLOT(view_zoom100())))->setCheckable(true); zoomGroup->addAction(zoomMenu->addAction("150%",this,SLOT(view_zoom150())))->setCheckable(true); zoomGroup->addAction(zoomMenu->addAction("200%",this,SLOT(view_zoom200())))->setCheckable(true); view_zoom50(); viewMenu->addSeparator(); viewMenu->addAction(databrowser->toggleViewAction()); viewMenu->addAction(dataeditor->toggleViewAction()); viewMenu->addAction(simcontrol->toggleViewAction()); QMenu * simulationMenu = this->menuBar()->addMenu(tr("Simulation")); simulationMenu->addAction("Run",simcontrol->getStepEngine(),SLOT(startPull()),QKeySequence("Ctrl+R")); simulationMenu->addAction("Pause",simcontrol->getStepEngine(),SLOT(stopPull()),QKeySequence("Ctrl+P")); simulationMenu->addAction("Reset to Initial Conditions",databackend->getUndoStack(),SLOT(undo()),QKeySequence("Ctrl+Shift+R")); QAction * a=simulationMenu->addAction("Warn Before Clearing Undo Stack"); a->setCheckable(true); a->setChecked(true); QObject::connect(a,SIGNAL(toggled(bool)),databackend,SLOT(setWarning(bool))); QMenu * dataMenu = this->menuBar()->addMenu(tr("Data")); dataMenu->addAction("Clear All Objects",databackend->getDataInserter(),SLOT(clearObjects())); dataMenu->addAction("Clear All Forces",databackend->getDataInserter(),SLOT(clearForces())); dataMenu->addAction("Clear All Macros",databackend->getDataInserter(),SLOT(clearMacros())); dataMenu->addAction("Clear All Constants",databackend->getDataInserter(),SLOT(clearConstants())); QMenu * helpMenu = this->menuBar()->addMenu(tr("Help")); helpMenu->addAction("Manual",this,SLOT(showManual())); helpMenu->addAction("About",this,SLOT(showAbout())); }
void preTick(const FrameEvent& evt) { clearForces(); }