void VesselSceneNode::snap(OrbiterDockingPort& ourPort, OrbiterDockingPort& theirPort) { ISceneNode* ourNode = ourPort.portNode; ISceneNode* theirNode = theirPort.portNode; theirNode->updateAbsolutePosition(); ourNode->updateAbsolutePosition(); //absolute rotation of the target port core::matrix4 theirMatrix = theirNode->getAbsoluteTransformation(); //Origin up and facing (inversed) of the target port core::vector3df theirDir = core::vector3df(0, 0, -1); core::vector3df theirRot = core::vector3df(0, 1, 0); //get absolute inversed facing and up direction of the target port theirMatrix.rotateVect(theirDir); theirMatrix.rotateVect(theirRot); theirDir.normalize(); theirRot.normalize(); //build rotation matrix to rotate from the ORIGIN of the source port to their ports current alignement core::matrix4 ourPortToTheirPort; ourPortToTheirPort.buildCameraLookAtMatrixLH(core::vector3df(0, 0, 0), theirDir, theirRot).makeInverse(); //get inverted source port rotation relative to its vessel core::matrix4 ourVesselToOurPort = ourNode->getRelativeTransformation(); ourVesselToOurPort.makeInverse(); //multiply the rotation from our vessel origin to our port and from our port origin to the target to get the total transformation for the vessel core::matrix4 ourVesselToTheirPort = ourPortToTheirPort * ourVesselToOurPort; //apply the whole brouhaha setRotation(ourVesselToTheirPort.getRotationDegrees()); //we MUST update positions for getAbsolutePosition to reflect the rotation we just did. //also, we MUST update the position of the parent before the child, or the child still won't reflect the changes //we also MUST update the child seperately, it doesn't get updated by the parent updateAbsolutePosition(); ourNode->updateAbsolutePosition(); //position the vessel so the docking ports touch core::vector3df pos = ourNode->getAbsolutePosition() - getAbsolutePosition(); setPosition(theirNode->getAbsolutePosition() - pos); //update the new position, in case there's a vessel being snapped to this right next updateAbsolutePosition(); }
int Java_zte_irrlib_scene_SceneNode_nativeUpdatePosition( JNIEnv* env, jobject defaultObj, jobject jvec, jboolean isAbsolute, jint Id) { ISceneNode* node = smgr->getSceneNodeFromId(Id); if (!node) { WARN_NODE_NOT_FOUND(Id, UpdatePosition); return -1; } if (isAbsolute) { node->updateAbsolutePosition(); utils->setVector3dFromvector3df(env, jvec, node->getAbsolutePosition()); } else utils->setVector3dFromvector3df(env, jvec, node->getPosition()); return 0; }
int Java_zte_irrlib_scene_SceneNode_nativeAddCollisionResponseAnimator( JNIEnv *env, jobject defaultObj, jint selId, jobject jradius, jboolean bbox, jboolean octree, jint id) { ISceneNode* selNode = smgr->getSceneNodeFromId(selId); if (!selNode) { WARN_NODE_NOT_FOUND(selId, AddCollisionResponseAnimator); return -1; } ISceneNode* node = smgr->getSceneNodeFromId(id); if (!node) { WARN_NODE_NOT_FOUND(id, AddCollisionResponseAnimator); return -1; } ITriangleSelector* selector = 0; if (bbox) selector = smgr->createTriangleSelectorFromBoundingBox(selNode); else if (!octree) selector = smgr->createTriangleSelector(((IMeshSceneNode*)selNode)->getMesh(), selNode); else selector = smgr->createTriangleSelector(((IMeshSceneNode*)selNode)->getMesh(), selNode); node->updateAbsolutePosition(); const aabbox3d<f32>& box = node->getTransformedBoundingBox(); vector3df radius; if (jradius == 0) radius = box.MaxEdge-box.getCenter(); else radius = utils->createvector3dfFromVector3d(env, jradius); vector3df translation = -(box.getCenter() - node->getAbsolutePosition()); //LOGD("max, %f, %f, %f", box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z); //LOGD("min, %f, %f, %f", box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z); //LOGD("trans, %f, %f, %f", translation.X, translation.Y, translation.Z); ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(selector, node, radius, vector3df(),/*gravity*/ translation, 0.0005f ); selector->drop(); node->addAnimator(anim); anim->drop(); }
int main(int argc, char** argv) { CustomEventReceiver receiver; IrrlichtDevice *device = createDevice( video::EDT_OPENGL, dimension2d<u32>(800, 600), 16, false, false, false, &receiver); if (!device) { return EXIT_FAILURE; } device->setWindowCaption(L"Solar System Simulator"); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* sceneManager = device->getSceneManager(); scene::ISceneCollisionManager* collisionManager= sceneManager->getSceneCollisionManager(); IGUIEnvironment* guiEnv = device->getGUIEnvironment(); guiEnv->addStaticText(L"Click on a planet to attach the camera to it", rect<s32>(10,10,260,22), false); sf::SoundBuffer buffer; if (buffer.loadFromFile(currentPath() + "/sounds/burning.aif")) { sf::Listener::setPosition(0, 0,0); sf::Sound sound; sound.setBuffer(buffer); sound.setPosition(0, 0, 0); sound.setLoop(true); sound.play(); } const char* spaceTexturePath = ( currentPath() + "/textures/space.jpg" ).c_str(); video::ITexture* space = driver->getTexture(spaceTexturePath); scene::ISceneNode* skybox = sceneManager->addSkyBoxSceneNode(space, space, space, space, space, space); sceneManager->addLightSceneNode(0, vector3df(0, 0, -50), video::SColorf(1.0f, 1.0f, 1.0f), 50.0f, 1001); PlanetFactory planetFactory(sceneManager, driver); Planet sun = planetFactory.create(PlanetId::Sun); Planet earth = planetFactory.create(PlanetId::Earth); Planet pluto = planetFactory.create(PlanetId::Pluto); Planet jupiter = planetFactory.create(PlanetId::Jupiter); Planet uranus = planetFactory.create(PlanetId::Uranus); Planet neptune = planetFactory.create(PlanetId::Neptune); vector<Planet> planets = { sun, planetFactory.create(PlanetId::Mercury) }; planets.push_back(planetFactory.create(PlanetId::Venus)); planets.push_back(earth); planets.push_back(planetFactory.create(PlanetId::Mars)); planets.push_back(jupiter); planets.push_back(planetFactory.create(PlanetId::Saturn)); planets.push_back(uranus); planets.push_back(neptune); planets.push_back(pluto); ICameraSceneNode* camera = sceneManager->addCameraSceneNode(0, vector3df(0,0,40), vector3df(0,0,0)); rect<s32> mainCameraViewPortRect(0, 0, 800, 600); ICameraSceneNode* topViewCamera = sceneManager->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0)); sceneManager->setAmbientLight(video::SColorf(255.0,255.0,255.0)); ISceneNode* selectedNode = sun.node; while(device->run()) { if(receiver.GetMouseState().LeftButtonDown) { position2di mousepos = receiver.GetMouseState().Position; line3df ray = sceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates( mousepos, camera); vector3df intersection; triangle3df tri; for(Planet& planet : planets) { ITriangleSelector* wselector = sceneManager->createTriangleSelectorFromBoundingBox(planet.node); if (collisionManager->getCollisionPoint(ray, wselector, intersection, tri, planet.node)) { selectedNode = planet.node; } wselector->drop(); } } camera->setTarget(selectedNode->getAbsolutePosition()); skybox->setVisible(true); driver->setViewPort(mainCameraViewPortRect); driver->beginScene(true, true, SColor(255,100,101,140)); sceneManager->setActiveCamera(camera); sceneManager->drawAll(); guiEnv->drawAll(); driver->setViewPort(rect<s32>(0, 380, 200, 600)); driver->draw2DRectangle(SColor(100,0,0,190), mainCameraViewPortRect); skybox->setVisible(false); sceneManager->setActiveCamera(topViewCamera); sceneManager->drawAll(); driver->endScene(); } device->drop(); return EXIT_SUCCESS; }