// Support function for finding collided nodes using a subset of nodes in the scene // recursive method for going through all scene nodes void getNodeRayBB(ISceneNode* root, const core::line3df& ray, s32 bits, bool recurse, f32& outbestdistance, ISceneNode*& outbestnode) { core::vector3df edges[8]; const core::list<ISceneNode*>& children = root->getChildren(); core::list<ISceneNode*>::ConstIterator it = children.begin(); for (; it != children.end(); ++it) { ISceneNode* current = *it; if (current->isVisible() && // (bNoDebugObjects ? !current->isDebugObject() : true) && (bits==0 || (bits != 0 && (current->getID() & bits)))) { // get world to object space transform core::matrix4 mat; if (!current->getAbsoluteTransformation().getInverse(mat)) continue; // transform vector from world space to object space core::line3df line(ray); mat.transformVect(line.start); mat.transformVect(line.end); const core::aabbox3df& box = current->getBoundingBox(); // do intersection test in object space if (box.intersectsWithLine(line)) { box.getEdges(edges); f32 distance = 0.0f; for (s32 e=0; e<8; ++e) { f32 t = edges[e].getDistanceFromSQ(line.start); if (t > distance) distance = t; } if (distance < outbestdistance) { outbestnode = current; outbestdistance = distance; } } } if ( recurse ) getNodeRayBB(current, ray, bits, recurse, outbestdistance, outbestnode); } }
int Java_zte_irrlib_scene_SceneNode_nativeGetAbsoluteMatrix( JNIEnv* env, jobject thiz, jobject jmat, jint Id) { ISceneNode* node = smgr->getSceneNodeFromId(Id); if (!node) { WARN_NODE_NOT_FOUND(Id, GetAbsoluteMatrix); return -1; } utils->setMatrix4Frommatrix4(env, jmat, node->getAbsoluteTransformation()); return 0; }
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(); }
// Support function for finding collided nodes using a subset of nodes in the scene // recursive method for going through all scene nodes and testing them against a point bool getNodePointBB(ISceneNode* root, vector3df point, s32 bits, bool recurse, ISceneNode*& outbestnode) { core::vector3df edges[8]; const core::list<ISceneNode*>& children = root->getChildren(); core::list<ISceneNode*>::ConstIterator it = children.begin(); for (; it != children.end(); ++it) { ISceneNode* current = *it; if (current->isVisible() && // (bNoDebugObjects ? !current->isDebugObject() : true) && (bits==0 || (bits != 0 && (current->getID() & bits)))) { // get world to object space transform core::matrix4 mat; if (!current->getAbsoluteTransformation().getInverse(mat)) continue; // transform vector from world space to object space vector3df currentPoint( point ); mat.transformVect(currentPoint); const core::aabbox3df& box = current->getBoundingBox(); // do intersection test in object space if (box.isPointInside( currentPoint )) { outbestnode = current; return true; } } if ( recurse ) if ( getNodePointBB(current, point, bits, recurse, outbestnode)) return true; } return false; }
void LayerNode::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); ISceneNode* cameraNode = SceneManager->getActiveCamera(); core::matrix4 mxTrans = cameraNode->getAbsoluteTransformation(); core::vector3df vCamPos = cameraNode->getPosition(); core::vector3df vCamScale = cameraNode->getScale(); core::vector3df vCamRot = cameraNode->getRotation(); //Zoom factor: for Factor=0, zoom = 1; for Factor=1, zoom = vCamScale; vCamScale.X = 1 - ( (1 - vCamScale.X) * m_paraxZoomFactor ); vCamScale.Y = 1 - ( (1 - vCamScale.Y) * m_paraxZoomFactor ); core::vector3df vCamPos2 = cameraNode->getPosition(); // Apply Offset core::vector3df vOffset(m_offsetX, m_offsetY, 0); // Apply parallax factor vCamPos2.X *= m_paraxFactorX; vCamPos2.Y *= m_paraxFactorY; mxTrans = core::matrix4().setTranslation(vCamPos)* core::matrix4().setScale(vCamScale)* core::matrix4().setTranslation(-vCamPos)* core::matrix4().setRotationDegrees(vCamRot)* core::matrix4().setTranslation(-vCamPos)* // remove camera offset because is applied automatically later by Irrlicht core::matrix4().setTranslation(vOffset)* // apply offset without parallax factor to make easy to adjust layer core::matrix4().setTranslation(vCamPos2) // then apply modified by parallax factor camera position ; driver->setMaterial(Material); driver->setTransform(video::ETS_WORLD, mxTrans*AbsoluteTransformation); Drawing::draw2DImage( driver, m_texture, core::recti( 0, 0, m_width, m_height), core::IdentityMatrix, true, video::SColor(255, 255, 255, 255)); }
void CImpostorSceneNode::renderNode(SNodeLink& Imp) { ISceneNode* n = Imp.Node; updatePosAndVector(Imp); // remember old viewport and render target core::rect<s32> oldView = SceneManager->getVideoDriver()->getViewPort(); if (!oldView.isRectCollided(Imp.NewPos)) return; ICameraSceneNode* cam = SceneManager->getActiveCamera(); cam->updateAbsolutePosition(); core::vector3df camP = cam->getAbsolutePosition(); f32 distance = camP.getDistanceFrom(n->getTransformedBoundingBox().getCenter()); // project into screen core::vector3df pUL = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(Imp.NewPos.UpperLeftCorner, cam).getVector(); pUL.setLength(distance); core::vector3df pLR = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(Imp.NewPos.LowerRightCorner, cam).getVector(); pLR.setLength(distance); core::vector3df pUR = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2di(Imp.NewPos.LowerRightCorner.X, Imp.NewPos.UpperLeftCorner.Y), cam).getVector(); pUR.setLength(distance); core::vector3df pLL = SceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates(core::position2di(Imp.NewPos.UpperLeftCorner.X, Imp.NewPos.LowerRightCorner.Y), cam).getVector(); pLL.setLength(distance); Imp.BilPos1 = camP + pUL; Imp.BilPos2 = camP + pLR; Imp.BilPos3 = camP + pUR; Imp.BilPos4 = camP + pLL; // translate and scale, but don't rotate core::matrix4 invMat = n->getAbsoluteTransformation(); invMat.makeInverse(); Imp.BilPos1 *= invMat.getScale(); invMat.translateVect(Imp.BilPos1); Imp.BilPos2 *= invMat.getScale(); invMat.translateVect(Imp.BilPos2); Imp.BilPos3 *= invMat.getScale(); invMat.translateVect(Imp.BilPos3); Imp.BilPos4 *= invMat.getScale(); invMat.translateVect(Imp.BilPos4); Imp.ScreenPos = Imp.NewPos; Imp.RotVec = Imp.NewVec; video::ITexture* rt = 0; // SceneManager->getVideoDriver()->getRenderTarget(); // set up the camera and viewport for rendering ISceneManager* oldManager = n->getSceneManager(); // set up the camera ICameraSceneNode* cam2= LocalManager->getActiveCamera(); cam2->setPosition(cam->getAbsolutePosition()); core::vector3df v = n->getTransformedBoundingBox().getCenter(); cam2->setUpVector(cam->getUpVector()); cam2->setTarget(cam->getTarget()); cam2->updateAbsolutePosition(); f32 scaleW = f32(oldView.getWidth()) / f32(Imp.ScreenPos.getWidth()); f32 scaleH = f32(oldView.getHeight()) / f32(Imp.ScreenPos.getHeight()); //f32 transW = f32(Impostors[i].ScreenPos.getWidth()/2) / (f32(oldView.getWidth()) - f32(Impostors[i].ScreenPos.getCenter().X)); //f32 transH = f32(Impostors[i].ScreenPos.getHeight()/2) / (f32(oldView.getHeight()) - f32(Impostors[i].ScreenPos.getCenter().X)); f32 transW = (f32(oldView.getCenter().X) - f32(Imp.ScreenPos.getCenter().X)) / f32(Imp.ScreenPos.getWidth()); f32 transH = (f32(oldView.getCenter().Y) - f32(Imp.ScreenPos.getCenter().Y)) / f32(Imp.ScreenPos.getHeight()); core::matrix4 proj(cam->getProjectionMatrix()); core::matrix4 zoom, trans; Imp.Time = Timer->getRealTime(); zoom.setScale(core::vector3df(scaleW, scaleH, 1.0)); trans.setTranslation(core::vector3df(transW*2,-transH*2,0.0)); proj = zoom * proj; #if defined(GENERATE_METHOD_1) proj = trans * proj; #endif // set the correct render target and viewport setTarget(Imp); // draw the scene cam2->setProjectionMatrix(proj); E_CULLING_TYPE culltype = EAC_FRUSTUM_BOX; n->setAutomaticCulling(EAC_OFF); //cam2->render(); // n->setSceneManager(LocalManager); n->OnRegisterSceneNode(); LocalManager->drawAll(); n->setAutomaticCulling(culltype); //s32 numberzzz = LocalManager->getParameters()->getAttributeAsInt("culled"); // copy work buffer back s32 slot = Buffers[Imp.BufferID].SlotSize; //SceneManager->getGUIEnvironment()->getBuiltInFont()->draw(L"HI THERE!", core::rect<s32>(0, 0, slot, slot), video::SColor(), true, true); SceneManager->getVideoDriver()->setRenderTarget(Buffers[ Imp.BufferID].Texture, false, true); //SceneManager->getVideoDriver()->setRenderTarget(0); //LocalManager->getVideoDriver()->setViewPort( core::rect<s32>(0,0,TextureWidth,TextureWidth) ); s32 d = TextureWidth / slot; s32 x = (Imp.SlotID % d) * slot; s32 y = (Imp.SlotID / d) * slot; //LocalManager->getVideoDriver()->setViewPort( core::rect<s32>(0,0,TextureWidth,TextureWidth) ); /* SceneManager->getVideoDriver()->draw2DRectangle( video::SColor(127,0,0,0), core::rect<s32>(x,y,x+slot,y+slot)); SceneManager->getVideoDriver()->draw2DRectangle( video::SColor(100,0,0,0), core::rect<s32>(x,y,x+slot,y+slot)); SceneManager->getVideoDriver()->draw2DRectangle( video::SColor(100,0,0,0), core::rect<s32>(x,y,x+slot,y+slot)); */ //SceneManager->getVideoDriver()->setTransform core::rect<s32> clipRect(x,y, x+slot,y+slot); video::SMaterial m; m.MaterialTypeParam =video::pack_texureBlendFunc(video::EBF_ONE, video::EBF_ONE_MINUS_DST_ALPHA, video::EMFN_MODULATE_1X); m.MaterialType = video::EMT_ONETEXTURE_BLEND; m.Lighting=false; m.ZBuffer = false; m.ZWriteEnable = false; m.TextureLayer[0].TextureWrapU = video::ETC_CLAMP; m.setTexture(0, WorkTexture); video::S3DVertex Vertices[6]; Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 0.0f, YDirection); Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 0.0f, 0.0f); Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 1.0f, 0.0f); Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 1.0f, YDirection); Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 0.0f, YDirection); Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,255,255,255), 1.0f, 0.0f); const u16 i1[] = {0,1,2,3,4,5}; const u16 i2[] = {0,2,1,3,5,4}; const u16* indices = i1; core::matrix4 matrix, matrix2; if (YDirection == -1.0f) { matrix2.setScale(core::vector3df(1.0f,-1.0f,1.0f)); indices = i2; } LocalManager->getVideoDriver()->setViewPort( clipRect ); LocalManager->getVideoDriver()->setMaterial(m); SceneManager->getVideoDriver()->setTransform(video::ETS_WORLD, matrix); SceneManager->getVideoDriver()->setTransform(video::ETS_PROJECTION, matrix2); SceneManager->getVideoDriver()->setTransform(video::ETS_VIEW, matrix); SceneManager->getVideoDriver()->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2); LocalManager->getVideoDriver()->setViewPort(core::rect<s32>(0,0,TextureWidth, TextureWidth)); //SceneManager->getVideoDriver()->draw2DImage( // WorkTexture, // core::position2di(x,y), // core::rect<s32>(0,0,slot, slot), // &clipRect, // video::SColor(255,255,255,255),true); if (DebugDataVisible & EDS_IMPOSTOR_INFO && DebugFont) { core::stringw text; video::SColor col(255,255,0,0); core::rect<s32> clip(x, y, x+slot, 0); s32 third = s32(f32(slot)*0.5f); text=L"Buf: "; text+=Imp.BufferID; clip.UpperLeftCorner.Y = y+third; clip.LowerRightCorner.Y = y+ third*2; DebugFont->draw(text.c_str(), clip, col, true, true, &clip); text=L"Region: "; text+=Imp.SlotID; clip.UpperLeftCorner.Y = y+third*2; clip.LowerRightCorner.Y = y+slot; DebugFont->draw(text.c_str(), clip, col, true, true, &clip); } //core::rect<s32> blaView = SceneManager->getVideoDriver()->getViewPort(); //SceneManager->getVideoDriver()->setTransform(video::ETS_WORLD, n->getAbsoluteTransformation()); //SceneManager->getVideoDriver()->draw3DBox(n->getBoundingBox()); // restore states SceneManager->getVideoDriver()->setRenderTarget(0, false, false); LocalManager->getVideoDriver()->setViewPort(oldView); // n->setSceneManager(oldManager); }