예제 #1
0
bool Laser::OnEvent( const SEvent& event )
{
	// Remember whether each key is down or up
	if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
	{

		if(lastPosX != event.MouseInput.X)
		{
			if ( (event.MouseInput.X > ((SCREEN_WIDTH - CAMERA_VIEW_WIDTH)* 0.5f) ) && 
				(event.MouseInput.X < ((SCREEN_WIDTH + CAMERA_VIEW_WIDTH)* 0.5f ) ) )
			{
				ICameraSceneNode* cam = SceneManager->getActiveCamera();
				const scene::SViewFrustum* f = cam->getViewFrustum();
	
				core::vector3df farLeftUp = f->getFarLeftUp();
				core::vector3df lefttoright = f->getFarRightUp() - farLeftUp;
				core::vector3df uptodown = f->getFarLeftDown() - farLeftUp;
	
				float diffX = lastPosX -  event.MouseInput.X;
				core::vector3df currentPos =  guidedLight->getPosition();
				lefttoright.normalize();
				core::vector3df finalPos = currentPos + (lefttoright * -diffX*0.5f) ;
	
				guidedLight->setPosition(finalPos);
				laserLight->setPosition(finalPos);
	
				lastPosX = event.MouseInput.X;
			}
		}
		
		if(lastPosY!= event.MouseInput.Y)
		{
			if ( (event.MouseInput.Y > ((SCREEN_HEIGHT - CAMERA_VIEW_HEIGHT)* 0.5f)  ) && 
				(event.MouseInput.Y < ((SCREEN_HEIGHT + CAMERA_VIEW_HEIGHT)* 0.5f  ) ) )
			{
				ICameraSceneNode* cam = SceneManager->getActiveCamera();
				const scene::SViewFrustum* f = cam->getViewFrustum();

				core::vector3df farLeftUp = f->getFarLeftUp();
				core::vector3df lefttoright = f->getFarRightUp() - farLeftUp;
				core::vector3df uptodown = f->getFarLeftDown() - farLeftUp;

				float diffY = lastPosY - event.MouseInput.Y;
				core::vector3df currentPos =  guidedLight->getPosition();
				uptodown.normalize();
				core::vector3df finalPos = currentPos + (uptodown * -diffY*0.5f) ;

				guidedLight->setPosition(finalPos);
				laserLight->setPosition(finalPos);

				lastPosY = event.MouseInput.Y;
			}
		}


		laserLight->setVisible(event.MouseInput.isLeftPressed());
		return true; //consume
	}
	return false;
}
예제 #2
0
// selectObject
// detect list objs at rect
void CDocument::selectObject( int x, int y, int w, int h, bool isControlHold )
{
	IView *pView = getIView();
	ISceneManager *smgr = pView->getSceneMgr();	
	
	ICameraSceneNode *camera = smgr->getActiveCamera();

	// if no camera
	if (  camera == NULL )
		return;

	const SViewFrustum* viewFrustum = camera->getViewFrustum();
	ISceneCollisionManager *collMan = smgr->getSceneCollisionManager();

	int screenX = -1, screenY = -1;
		
	ArrayZoneIter iZone = m_zones.begin(), iEnd = m_zones.end();
	while ( iZone != iEnd )
	{
		ArrayGameObject* listObj = (*iZone)->getChilds();
		ArrayGameObjectIter iObj = listObj->begin(), objEnd = listObj->end();
		ISceneNode *pNode = NULL;

		while ( iObj != objEnd )
		{
			CGameObject *pGameObj = (CGameObject*)(*iObj);
			
			pNode = pGameObj->getSceneNode();
			
			if ( pNode != NULL && pGameObj->isVisible() )
			{
				core::vector3df center = pGameObj->getPosition();

				// check object is in frustum
				if ( viewFrustum->getBoundingBox().isPointInside( center ) )
				{					
					if ( pView->getScreenCoordinatesFrom3DPosition( center, &screenX, &screenY ) )
					{
						if ( x <= screenX && screenX <= x + w && y <= screenY && screenY <= y + h )
						{
							
							if ( isControlHold == false || pGameObj->getObjectState() == CGameObject::Normal )
								m_selectObjects.push_back( pGameObj );							

						}	// inselect
					}	// getScreenCoordinatesFrom3DPosition			
				} // frustum
			}

			iObj++;
		}

		iZone++;
	}

}
예제 #3
0
//! renders the node.
void COctTreeSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();

	if (vertexType == -1 || !driver)
		return;

	ICameraSceneNode* camera = SceneManager->getActiveCamera();
	if (!camera)
		return;

	bool isTransparentPass =
		SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
	++PassCount;

	driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

	SViewFrustum frust = *camera->getViewFrustum();

	//transform the frustum to the current absolute transformation
	core::matrix4 invTrans(AbsoluteTransformation);
	invTrans.makeInverse();

	frust.transform(invTrans);
	/*
	//const core::aabbox3d<float> &box = frust.getBoundingBox();
	*/

	switch(vertexType)
	{
	case video::EVT_STANDARD:
		{
			//StdOctTree->calculatePolys(box);
			StdOctTree->calculatePolys(frust);

			const OctTree<video::S3DVertex>::SIndexData* d = StdOctTree->getIndexData();

			for (u32 i=0; i<Materials.size(); ++i)
			{
				if ( 0 == d[i].CurrentSize )
					continue;

				const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
				const bool transparent = (rnd && rnd->isTransparent());

				// only render transparent buffer if this is the transparent render pass
				// and solid only in solid pass
				if (transparent == isTransparentPass)
				{
					driver->setMaterial(Materials[i]);
					driver->drawIndexedTriangleList(
						&StdMeshes[i].Vertices[0], StdMeshes[i].Vertices.size(),
						d[i].Indices, d[i].CurrentSize / 3);
				}
			}

			// for debug purposes only
			if (DebugDataVisible && !Materials.empty() && PassCount==1)
			{
				const core::aabbox3df& box = frust.getBoundingBox();
				core::array< const core::aabbox3d<f32>* > boxes;
				video::SMaterial m;
				m.Lighting = false;
				driver->setMaterial(m);
				if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
				{
					StdOctTree->getBoundingBoxes(box, boxes);
					for (u32 b=0; b!=boxes.size(); ++b)
						driver->draw3DBox(*boxes[b]);
				}

				if ( DebugDataVisible & scene::EDS_BBOX )
					driver->draw3DBox(Box,video::SColor(0,255,0,0));
			}
		}
		break;
	case video::EVT_2TCOORDS:
		{
			//LightMapOctTree->calculatePolys(box);
			LightMapOctTree->calculatePolys(frust);

			const OctTree<video::S3DVertex2TCoords>::SIndexData* d = LightMapOctTree->getIndexData();

			for (u32 i=0; i<Materials.size(); ++i)
			{
				if ( 0 == d[i].CurrentSize )
					continue;

				const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
				const bool transparent = (rnd && rnd->isTransparent());

				// only render transparent buffer if this is the transparent render pass
				// and solid only in solid pass
				if (transparent == isTransparentPass)
				{
					driver->setMaterial(Materials[i]);
					driver->drawIndexedTriangleList(
						&LightMapMeshes[i].Vertices[0], LightMapMeshes[i].Vertices.size(),
						d[i].Indices, d[i].CurrentSize / 3);
				}
			}

			// for debug purposes only
			if (DebugDataVisible && !Materials.empty() && PassCount==1)
			{
				const core::aabbox3d<float> &box = frust.getBoundingBox();
				core::array< const core::aabbox3d<f32>* > boxes;
				video::SMaterial m;
				m.Lighting = false;
				driver->setMaterial(m);
				if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
				{
					LightMapOctTree->getBoundingBoxes(box, boxes);
					for (u32 b=0; b<boxes.size(); ++b)
						driver->draw3DBox(*boxes[b]);
				}

				if ( DebugDataVisible & scene::EDS_BBOX )
					driver->draw3DBox(Box,video::SColor(0,255,0,0));
			}
		}
		break;
	case video::EVT_TANGENTS:
		{
			//TangentsOctTree->calculatePolys(box);
			TangentsOctTree->calculatePolys(frust);

			const OctTree<video::S3DVertexTangents>::SIndexData* d =  TangentsOctTree->getIndexData();

			for (u32 i=0; i<Materials.size(); ++i)
			{
				if ( 0 == d[i].CurrentSize )
					continue;

				const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
				const bool transparent = (rnd && rnd->isTransparent());

				// only render transparent buffer if this is the transparent render pass
				// and solid only in solid pass
				if (transparent == isTransparentPass)
				{
					driver->setMaterial(Materials[i]);
					driver->drawIndexedTriangleList(
						&TangentsMeshes[i].Vertices[0], TangentsMeshes[i].Vertices.size(),
						d[i].Indices, d[i].CurrentSize / 3);
				}
			}

			// for debug purposes only
			if (DebugDataVisible && !Materials.empty() && PassCount==1)
			{
				const core::aabbox3d<float> &box = frust.getBoundingBox();
				core::array< const core::aabbox3d<f32>* > boxes;
				video::SMaterial m;
				m.Lighting = false;
				driver->setMaterial(m);
				if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
				{
					TangentsOctTree->getBoundingBoxes(box, boxes);
					for (u32 b=0; b<boxes.size(); ++b)
						driver->draw3DBox(*boxes[b]);
				}

				if ( DebugDataVisible & scene::EDS_BBOX )
					driver->draw3DBox(Box,video::SColor(0,255,0,0));
			}
		}
		break;
	}
}
//! renders the node.
void COctreeSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();

	if (!driver)
		return;

	ICameraSceneNode* camera = SceneManager->getActiveCamera();
	if (!camera)
		return;

	bool isTransparentPass =
		SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
	++PassCount;

	driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

	if (Shadow)
		Shadow->updateShadowVolumes();

	SViewFrustum frust = *camera->getViewFrustum();

	//transform the frustum to the current absolute transformation
	if ( !AbsoluteTransformation.isIdentity() )
	{
		core::matrix4 invTrans(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE);
		frust.transform(invTrans);
	}

	const core::aabbox3d<float> &box = frust.getBoundingBox();

	if (BoxBased)
		StdOctree->calculatePolys(box);
	else
		StdOctree->calculatePolys(frust);

	const Octree::SIndexData* d = StdOctree->getIndexData();

	for (u32 i=0; i<Materials.size(); ++i)
	{
		if ( 0 == d[i].CurrentSize )
			continue;

		const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
		const bool transparent = (rnd && rnd->isTransparent());

		// only render transparent buffer if this is the transparent render pass
		// and solid only in solid pass
		if (transparent == isTransparentPass)
		{
			driver->setMaterial(Materials[i]);

			if (UseVBOs)
			{
				if (UseVisibilityAndVBOs)
				{
					scene::IIndexBuffer* oldBuffer = StdMeshes[i]->getIndexBuffer();
					oldBuffer->grab();

					StdMeshes[i]->setIndexBuffer(d[i].IndexBuffer);
					StdMeshes[i]->setDirty(scene::EBT_INDEX);

					driver->drawMeshBuffer ( StdMeshes[i] );

					StdMeshes[i]->setIndexBuffer(oldBuffer);
					oldBuffer->drop();

					StdMeshes[i]->setDirty(scene::EBT_INDEX);
				}
				else
					driver->drawMeshBuffer ( StdMeshes[i] );
			}
			else
				driver->drawIndexedTriangleList(false, StdMeshes[i]->getVertexBuffer(), false, d[i].IndexBuffer, d[i].CurrentSize / 3);
		}
	}

	// for debug purposes only
	if (DebugDataVisible && !Materials.empty() && PassCount==1)
	{
		const core::aabbox3d<float> &box = frust.getBoundingBox();
		core::array< const core::aabbox3d<f32>* > boxes;
		video::SMaterial m;
		m.Lighting = false;
		driver->setMaterial(m);
		if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
		{
			StdOctree->getBoundingBoxes(box, boxes);
			for (u32 b=0; b<boxes.size(); ++b)
				driver->draw3DBox(*boxes[b]);
		}

		if ( DebugDataVisible & scene::EDS_BBOX )
			driver->draw3DBox(Box,video::SColor(0,255,0,0));
	}
}
예제 #5
0
//! render
void CParticleSystemSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	ICameraSceneNode* camera = SceneManager->getActiveCamera();

	if (!camera || !driver)
		return;


#if 0
	// calculate vectors for letting particles look to camera
	core::vector3df view(camera->getTarget() - camera->getAbsolutePosition());
	view.normalize();

	view *= -1.0f;

#else

	const core::matrix4 &m = camera->getViewFrustum()->getTransform( video::ETS_VIEW );

	const core::vector3df view ( -m[2], -m[6] , -m[10] );

#endif

	// reallocate arrays, if they are too small
	reallocateBuffers();

	// create particle vertex data
	s32 idx = 0;
	for (u32 i=0; i<Particles.size(); ++i)
	{
		const SParticle& particle = Particles[i];

		#if 0
			core::vector3df horizontal = camera->getUpVector().crossProduct(view);
			horizontal.normalize();
			horizontal *= 0.5f * particle.size.Width;

			core::vector3df vertical = horizontal.crossProduct(view);
			vertical.normalize();
			vertical *= 0.5f * particle.size.Height;

		#else
			f32 f;

			f = 0.5f * particle.size.Width;
			const core::vector3df horizontal ( m[0] * f, m[4] * f, m[8] * f );

			f = -0.5f * particle.size.Height;
			const core::vector3df vertical ( m[1] * f, m[5] * f, m[9] * f );
		#endif

		Buffer->Vertices[0+idx].Pos = particle.pos + horizontal + vertical;
		Buffer->Vertices[0+idx].Color = particle.color;
		Buffer->Vertices[0+idx].Normal = view;

		Buffer->Vertices[1+idx].Pos = particle.pos + horizontal - vertical;
		Buffer->Vertices[1+idx].Color = particle.color;
		Buffer->Vertices[1+idx].Normal = view;

		Buffer->Vertices[2+idx].Pos = particle.pos - horizontal - vertical;
		Buffer->Vertices[2+idx].Color = particle.color;
		Buffer->Vertices[2+idx].Normal = view;

		Buffer->Vertices[3+idx].Pos = particle.pos - horizontal + vertical;
		Buffer->Vertices[3+idx].Color = particle.color;
		Buffer->Vertices[3+idx].Normal = view;

		idx +=4;
	}

	// render all
	core::matrix4 mat;
	if (!ParticlesAreGlobal)
		mat.setTranslation(AbsoluteTransformation.getTranslation());
	driver->setTransform(video::ETS_WORLD, mat);

	driver->setMaterial(Buffer->Material);

	driver->drawVertexPrimitiveList(Buffer->getVertices(), Particles.size()*4,
		Buffer->getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES,Buffer->getIndexType());

	// for debug purposes only:
	if ( DebugDataVisible & scene::EDS_BBOX )
	{
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		video::SMaterial deb_m;
		deb_m.Lighting = false;
		driver->setMaterial(deb_m);
		driver->draw3DBox(Buffer->BoundingBox, video::SColor(0,255,255,255));
	}
}
//! OnAnimate() is called just before rendering the whole scene.
//! nodes may calculate or store animations here, and may do other useful things,
//! dependent on what they are.
void CSceneNodeAnimatorCameraMaya::animateNode(ISceneNode *node, u32 timeMs)
{
	//Alt + LM = Rotate around camera pivot
	//Alt + LM + MM = Dolly forth/back in view direction (speed % distance camera pivot - max distance to pivot)
	//Alt + MM = Move on camera plane (Screen center is about the mouse pointer, depending on move speed)

	if (node->getType() != ESNT_CAMERA)
		return;

	ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);

	if (OldCamera != camera)
	{
		OldTarget = camera->getTarget();
		OldCamera = camera;
	}

	Target = camera->getTarget();

	const SViewFrustum* va = camera->getViewFrustum();

	f32 nRotX = RotX;
	f32 nRotY = RotY;
	f32 nZoom = CurrentZoom;

	if ( (isMouseKeyDown(0) && isMouseKeyDown(2)) || isMouseKeyDown(1) )
	{
		if (!Zooming)
		{
			ZoomStartX = MousePos.X;
			ZoomStartY = MousePos.Y;
			Zooming = true;
			nZoom = CurrentZoom;
		}
		else
		{
			f32 old = nZoom;
			nZoom += (ZoomStartX - MousePos.X) * ZoomSpeed;

			f32 targetMinDistance = 0.1f;
			if (nZoom < targetMinDistance) // jox: fixed bug: bounce back when zooming to close
				nZoom = targetMinDistance;

			if (nZoom < 0)
				nZoom = old;
		}
	}
	else
	{
		if (Zooming)
		{
			f32 old = CurrentZoom;
			CurrentZoom = CurrentZoom + (ZoomStartX - MousePos.X ) * ZoomSpeed;
			nZoom = CurrentZoom;

			if (nZoom < 0)
				nZoom = CurrentZoom = old;
		}

		Zooming = false;
	}

	// Translation ---------------------------------

	core::vector3df translate(OldTarget), UpVector(camera->getUpVector());

	core::vector3df tvectX = Pos - Target;
	tvectX = tvectX.crossProduct(UpVector);
	tvectX.normalize();

	core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown());
	tvectY = tvectY.crossProduct(UpVector.Y > 0 ? Pos - Target : Target - Pos);
	tvectY.normalize();
	

	if (isMouseKeyDown(2) && !Zooming)
	{
		if (!Translating)
		{
			TranslateStartX = MousePos.X;
			TranslateStartY = MousePos.Y;
			Translating = true;
		}
		else
		{
			translate +=  tvectX * (TranslateStartX - MousePos.X)*TranslateSpeed + 
			              tvectY * (TranslateStartY - MousePos.Y)*TranslateSpeed;
		}
	}
	else
	{
		if (Translating)
		{
			translate += tvectX * (TranslateStartX - MousePos.X)*TranslateSpeed + 
			             tvectY * (TranslateStartY - MousePos.Y)*TranslateSpeed;
			OldTarget = translate;
		}

		Translating = false;
	}

	// Rotation ------------------------------------

	if (isMouseKeyDown(0) && !Zooming)
	{
		if (!Rotating)
		{
			RotateStartX = MousePos.X;
			RotateStartY = MousePos.Y;
			Rotating = true;
			nRotX = RotX;
			nRotY = RotY;
		}
		else
		{
			nRotX += (RotateStartX - MousePos.X) * RotateSpeed;
			nRotY += (RotateStartY - MousePos.Y) * RotateSpeed;
		}
	}
	else
	{
		if (Rotating)
		{
			RotX = RotX + (RotateStartX - MousePos.X) * RotateSpeed;
			RotY = RotY + (RotateStartY - MousePos.Y) * RotateSpeed;
			nRotX = RotX;
			nRotY = RotY;
		}

		Rotating = false;
	}

	// Set Pos ------------------------------------

	Target = translate;

	Pos.X = nZoom + Target.X;
	Pos.Y = Target.Y;
	Pos.Z = Target.Z;

	Pos.rotateXYBy(nRotY, Target);
	Pos.rotateXZBy(-nRotX, Target);

	// Rotation Error ----------------------------

	// jox: fixed bug: jitter when rotating to the top and bottom of y
	UpVector.set(0,1,0);
	UpVector.rotateXYBy(-nRotY);
	UpVector.rotateXZBy(-nRotX+180.f);

	camera->setPosition(Pos);
	camera->setTarget(Target);
	camera->setUpVector(UpVector);
}
//! OnAnimate() is called just before rendering the whole scene.
//! nodes may calculate or store animations here, and may do other useful things,
//! dependent on what they are.
void CSceneNodeAnimatorCameraMaya::animateNode(ISceneNode *node, u32 timeMs)
{
	//Alt + LM = Rotate around camera pivot
	//Alt + LM + MM = Dolly forth/back in view direction (speed % distance camera pivot - max distance to pivot)
	//Alt + MM = Move on camera plane (Screen center is about the mouse pointer, depending on move speed)

	if (!node || node->getType() != ESNT_CAMERA)
		return;

	ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);

	// If the camera isn't the active camera, and receiving input, then don't process it.
	if(!camera->isInputReceiverEnabled())
		return;

	scene::ISceneManager * smgr = camera->getSceneManager();
	if(smgr && smgr->getActiveCamera() != camera)
		return;

	if (OldCamera != camera)
	{
		OldTarget = camera->getTarget();
		OldCamera = camera;
		LastCameraTarget = OldTarget;
	}
	else
	{
		OldTarget += camera->getTarget() - LastCameraTarget;
	}

	core::vector3df target = camera->getTarget();

	f32 nRotX = RotX;
	f32 nRotY = RotY;
	f32 nZoom = CurrentZoom;

	if ( (isMouseKeyDown(0) && isMouseKeyDown(2)) || isMouseKeyDown(1) )
	{
		if (!Zooming)
		{
			ZoomStart = MousePos;
			Zooming = true;
			nZoom = CurrentZoom;
		}
		else
		{
			const f32 targetMinDistance = 0.1f;
			nZoom += (ZoomStart.X - MousePos.X) * ZoomSpeed;

			if (nZoom < targetMinDistance) // jox: fixed bug: bounce back when zooming to close
				nZoom = targetMinDistance;
		}
	}
	else if (Zooming)
	{
		const f32 old = CurrentZoom;
		CurrentZoom = CurrentZoom + (ZoomStart.X - MousePos.X ) * ZoomSpeed;
		nZoom = CurrentZoom;

		if (nZoom < 0)
			nZoom = CurrentZoom = old;
		Zooming = false;
	}

	// Translation ---------------------------------

	core::vector3df translate(OldTarget), upVector(camera->getUpVector());

	core::vector3df tvectX = Pos - target;
	tvectX = tvectX.crossProduct(upVector);
	tvectX.normalize();

	const SViewFrustum* const va = camera->getViewFrustum();
	core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown());
	tvectY = tvectY.crossProduct(upVector.Y > 0 ? Pos - target : target - Pos);
	tvectY.normalize();

	if (isMouseKeyDown(2) && !Zooming)
	{
		if (!Translating)
		{
			TranslateStart = MousePos;
			Translating = true;
		}
		else
		{
			translate +=  tvectX * (TranslateStart.X - MousePos.X)*TranslateSpeed +
			              tvectY * (TranslateStart.Y - MousePos.Y)*TranslateSpeed;
		}
	}
	else if (Translating)
	{
		translate += tvectX * (TranslateStart.X - MousePos.X)*TranslateSpeed +
		             tvectY * (TranslateStart.Y - MousePos.Y)*TranslateSpeed;
		OldTarget = translate;
		Translating = false;
	}

	// Rotation ------------------------------------

	if (isMouseKeyDown(0) && !Zooming)
	{
		if (!Rotating)
		{
			RotateStart = MousePos;
			Rotating = true;
			nRotX = RotX;
			nRotY = RotY;
		}
		else
		{
			nRotX += (RotateStart.X - MousePos.X) * RotateSpeed;
			nRotY += (RotateStart.Y - MousePos.Y) * RotateSpeed;
		}
	}
	else if (Rotating)
	{
		RotX += (RotateStart.X - MousePos.X) * RotateSpeed;
		RotY += (RotateStart.Y - MousePos.Y) * RotateSpeed;
		nRotX = RotX;
		nRotY = RotY;
		Rotating = false;
	}

	// Set Pos ------------------------------------

	target = translate;

	Pos.X = nZoom + target.X;
	Pos.Y = target.Y;
	Pos.Z = target.Z;

	Pos.rotateXYBy(nRotY, target);
	Pos.rotateXZBy(-nRotX, target);

	// Rotation Error ----------------------------

	// jox: fixed bug: jitter when rotating to the top and bottom of y
	upVector.set(0,1,0);
	upVector.rotateXYBy(-nRotY);
	upVector.rotateXZBy(-nRotX+180.f);

	camera->setPosition(Pos);
	camera->setTarget(target);
	camera->setUpVector(upVector);
	LastCameraTarget = camera->getTarget();
}
예제 #8
0
ISceneNode* CCombatSimulatorView::SelectNode(position2di mouse_pos)
{

	scene::ISceneCollisionManager* pCollMgr = p_smgr->getSceneCollisionManager();


	vector2d<s32> cursor = p_device->getCursorControl()->getPosition();

	core::line3d<f32> ln(0,0,0,0,0,0);

	ICameraSceneNode* camera = p_smgr->getActiveCamera();

	const scene::SViewFrustum* f = camera->getViewFrustum();

	core::vector3df farLeftUp = f->getFarLeftUp();
	core::vector3df lefttoright = f->getFarRightUp() - farLeftUp;
	core::vector3df uptodown = f->getFarLeftDown() - farLeftUp;

	RECT m_rect;
	this->GetWindowRect( &m_rect);



	f32 dx = (cursor.X + m_rect.left)  / (f32) (m_rect.right - m_rect.left) ;
	f32 dy = (cursor.Y + m_rect.top) / (f32) (m_rect.bottom - m_rect.top);

	if (camera->isOrthogonal())
		ln.start = f->cameraPosition + (lefttoright * (dx-0.5f)) + (uptodown * (dy-0.5f));
	else
		ln.start = f->cameraPosition;

	ln.end = farLeftUp + (lefttoright * dx) + (uptodown * dy);

	if ( ln.start == ln.end )
		return 0;


	ISceneNode* pNode = pCollMgr->getSceneNodeFromRayBB(ln, 0, true, p_ShipParent);

	if( pNode )
	{
		irr::core::list<ISceneNode*> list = pNode->getChildren();
		irr::core::list<ISceneNode*>::Iterator it = list.begin();
		ESCENE_NODE_TYPE t = pNode->getType();
		if (pNode->getType() == ESNT_SPHERE)
			pNode->setVisible(false);
		for (it;it != list.end(); it++)
		{
			if ((*it)->getType() ==ESNT_SPHERE)
			{
				if ( (*it)->isVisible())
					(*it)->setVisible(false);
				else
					(*it)->setVisible(true);
			}
		}

	}


	return pNode;


}
// render
// ISceneNode implement
void CGameStaticShadowSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	ICameraSceneNode* camera = SceneManager->getActiveCamera();

	if (!camera || !driver)
		return;

	const core::matrix4 &m = camera->getViewFrustum()->getTransform( video::ETS_VIEW );
	const core::vector3df view ( -m[2], -m[6] , -m[10] );

	// get shadow comp
	CShadowComponent* shadow = (CShadowComponent*)m_owner->getComponent(IObjectComponent::Shadow);
	if ( shadow == NULL )
		return;

	// make buffer by shadow pos
	std::vector<video::S3DVertex>& listShadow = shadow->getListShadow();
	int nShadow = (int)listShadow.size();

	if ( nShadow > 0 )
	{
		// create shadow mesh buffer
		reallocateBuffers(nShadow);
		
		s32 idx = 0;

		std::vector<video::S3DVertex>::iterator i = listShadow.begin(), end = listShadow.end();
		while (i != end)
		{
			core::vector3df pos = i->Pos;
			core::vector3df nor = i->Normal;
			float width		= 80.0f;
			float height	= 80.0f;

			// set texcoord
			Buffer->Vertices[0+idx].TCoords.set(0.0f, 0.0f);
			Buffer->Vertices[1+idx].TCoords.set(0.0f, 1.0f);
			Buffer->Vertices[2+idx].TCoords.set(1.0f, 1.0f);
			Buffer->Vertices[3+idx].TCoords.set(1.0f, 0.0f);
			
			// calc plane position
			f32 f = 0.5f * width;
			core::vector3df horizontal ( f, 0, 0 );

			f = -0.5f * height;
			core::vector3df vertical ( 0, 0, f );

			// rotate plane
			core::quaternion quaternion; 			
			quaternion.rotationFromTo( core::vector3df(0.0f,1.0f,0.0f), nor );

			core::matrix4 matrix = quaternion.getMatrix(); 
			matrix.rotateVect(horizontal); 
			matrix.rotateVect(vertical);


			// update buffer position
			Buffer->Vertices[0+idx].Pos = pos + horizontal + vertical;
			Buffer->Vertices[0+idx].Color = SColor(255,0,0,0);
			Buffer->Vertices[0+idx].Normal = nor;

			Buffer->Vertices[1+idx].Pos = pos + horizontal - vertical;
			Buffer->Vertices[1+idx].Color = SColor(255,0,0,0);
			Buffer->Vertices[1+idx].Normal = nor;

			Buffer->Vertices[2+idx].Pos = pos - horizontal - vertical;
			Buffer->Vertices[2+idx].Color = SColor(255,0,0,0);
			Buffer->Vertices[2+idx].Normal = nor;

			Buffer->Vertices[3+idx].Pos = pos - horizontal + vertical;
			Buffer->Vertices[3+idx].Color = SColor(255,0,0,0);
			Buffer->Vertices[3+idx].Normal = nor;

			idx += 4;

			Buffer->BoundingBox.addInternalPoint(pos);
			++i;
		}

		// render all
		core::matrix4 mat;
		driver->setTransform(video::ETS_WORLD, mat);

		// render 2 face on nonbillboard particle
		Buffer->Material.BackfaceCulling = false;
		Buffer->Material.FrontfaceCulling = false;
        
        Buffer->Material.Lighting = false;

		driver->setMaterial(Buffer->Material);

		driver->drawVertexPrimitiveList(
				Buffer->getVertices(), 
				nShadow*4,
				Buffer->getIndices(), 
				nShadow*2,
				video::EVT_STANDARD, EPT_TRIANGLES,
				Buffer->getIndexType()
			);
	}

	listShadow.clear();
}
예제 #10
0
void CImpostorSceneNode::OnRegisterSceneNode()
{
	if (!IsVisible)
		return;

	RenderCount++;

	// in here we:
	// decide which nodes need updates, add them to the queue
	// process the render queue
	//  allocate textures and mesh buffers if required
	// perform clean up tasks:
	//  garbage collection- free up spaces
	//  reorganise


	// get collision manager
	ISceneCollisionManager* colmgr = SceneManager->getSceneCollisionManager();

	// and the active camera
	ICameraSceneNode* cam = SceneManager->getActiveCamera();
	core::aabbox3df camBB = cam->getViewFrustum()->getBoundingBox();
	u32 now = Timer->getRealTime();

	// loop through all impostor nodes
	u32 i;
	for (i=0; i < Impostors.size(); ++i)
	{
		SNodeLink &Imp = Impostors[i];
		ISceneNode *n = Imp.Node;

		// skip invisible and culled nodes
		if (!n->isVisible() || !camBB.intersectsWithBox(n->getTransformedBoundingBox()))
		{
			//Culled++;
			Imp.IsActive = false;
			continue;
		}

		updatePosAndVector(Imp);

		// now we have the screen position...
		core::rect<s32> r = SceneManager->getVideoDriver()->getViewPort();

		if (!Imp.NewPos.isValid() || !r.isRectCollided(Imp.NewPos) )
		{
			// culled
			// Culled++;
			continue;
		}

		core::dimension2di newSize = Imp.NewPos.getSize();

		// Change in rotation: a.length >= a.dotProduct(b) <= -a.length
		f32 diff = 0;

		// far plane = never update, near plane = always update
		f32 far = cam->getFarValue();
		far *= far;
		f32 dist = Imp.Node->getAbsolutePosition().getDistanceFromSQ(cam->getAbsolutePosition());
		dist = 1.0 - (far/dist); // value between 0 and 1
		diff = dist;
		Imp.Score = dist;

		//s32 a = core::max_<s32>(Imp.NewPos.getWidth(), Imp.NewPos.getHeight());
		//diff *= f32(a);

		bool reRender = diff > Threshold;
		//reRender =true;

		reRender = reRender ||
			( !Imp.IsQueued && Imp.BufferID != -1 &&
			Buffers[Imp.BufferID].SlotSize < getTextureSizeFromSurfaceSize(core::max_<s32>(newSize.Width, newSize.Height)));

		// so small that we don't care about it
		if (newSize.Width < 4 || newSize.Height < 4)
		{
			Imp.IsActive = false;
			// object was culled
			//Culled++;
			continue;
		}

		// too large to fit in a texture slot
		if (newSize.Width > MaxSize || newSize.Height > MaxSize)
		{
			// get rid
			releaseSlot(Imp);
			Imp.IsActive = false;
		}
		else
		{
			Imp.IsActive = true;
		}

		if (Imp.IsActive && Imp.BufferID == -1 && !Imp.IsQueued )
			reRender = true;

		if (Imp.IsActive)
		{
			// impostor replaces the node
			if (reRender && now > Imp.Time + MinTime)
			{

				if (!Imp.IsQueued)
				{
					CacheMisses++;

					Imp.IsQueued = true;

					SRenderQueueItem q;
					q.Node = &Imp;
					//q.Value = val;

					RenderQueue.push_back(q);
				}
				else
				{
					//QueueHits++;
				}
			}
			else
			{
				// don't re-render the impostor texture, only draw it
				CacheHits++;
			}
		}
		if (!Imp.IsActive) // || ( Imp.BufferID == -1 && Imp.IsQueued))
		{
			// original node is visible
			n->OnRegisterSceneNode();
			// cache miss
			CacheMisses++;
		}
	}

	SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
}