Beispiel #1
0
		Air::U1 MeshEntity::RayCast( const Ray& ray ,float*	pOutDistance)
		{
#if 1
			if(!GetWorldBoundingBox().RayCast(ray.GetOrigin(),ray.GetDirection())){//.Intersect(GetWorldBoundingBox())){
				return	false;
			}
#endif

			Matrix	matWorld	=	*GetWorldMatrix();
			Matrix	matWorldInv	=	matWorld;
			matWorldInv.Inverse();
			Float3	vStart	=	ray.m_vStart;
			Float3	vLookAt	=	vStart	+	ray.m_vDirection;
			vStart			=	matWorldInv*vStart;
			vLookAt			=	matWorldInv*vLookAt;
			Float3	vDir	=	(vLookAt	-	vStart);
			vDir.Normalize();

			Ray	objSpaceRay(vStart,vDir);

			float	fDistance	=	999999.0f;

			U1	bHit	=	m_pMesh->RayCast(objSpaceRay,&fDistance);
			if(bHit	&&	pOutDistance!=NULL){
				Float3	vObjSpaceHitPostion		=	vStart	+	vDir*fDistance;
				Float3	vWorldSpaceHiPosition	=	matWorld*vObjSpaceHitPostion;
				*pOutDistance	=	(vWorldSpaceHiPosition	-	ray.m_vStart).Length();
			}
			return	bHit;
		}
Beispiel #2
0
		Air::U1 Actor::Move(float fTimeDelta)
		{
			if(m_MoveState==enAMS_NoMove){
				return false;
			}

			Float3	vMoveDir	=	m_vMoveDir;
			vMoveDir.y=0.0f;
			vMoveDir.Normalize();

			Float3 vOldPos		=	m_pNode->GetPosition();
			Float3	vCurrentPos	=	m_pNode->GetPosition();
			//vCurrentPos			+=	vMoveDir*fSensitivity;
			Float3 vNewVelocity	=	vMoveDir*m_fMoveVelocity;
			vNewVelocity.y	=	m_vMoveDir.y;
			PhysicsSystem::GetSingleton()->Silumation(vCurrentPos,0.5,1,vNewVelocity,fTimeDelta);
			m_vMoveDir.y		=	vNewVelocity.y;
			if(vCurrentPos.y<-1){
				vCurrentPos.y=1;
				m_vMoveDir.y		=	0;
			}

			m_pNode->SetPosition(vCurrentPos);

			return true;
		}
Beispiel #3
0
		Air::Ray Frustum::BuildRay( Real x,Real y )
		{
#if 0
			POINT point;

			point.x	=	x;
			point.y	=	y;


			Common::Matrix mInverseView	=	m_matView;
			mInverseView.Inverse();

			// Compute the vector of the pick ray in screen space
			Float3 v;
			v.x = ( ( ( 2.0f * point.x ) / m_iScreenWidth ) - 1 ) /m_matProj.m00;
			v.y = -( ( ( 2.0f * point.y ) / m_iScreenHeight ) - 1 ) /m_matProj.m11;
			//如果是右手坐标系 Z必须为-1 左手坐标系为1 切需注意
			v.z = 1;//-m_ShaderParam.m_matProj[3][2];

			Ray ray;

			// Transform the screen space pick ray into 3D space
			ray.m_vDirection.x = v.x * mInverseView.m00 + v.y * mInverseView.m10 + v.z * mInverseView.m20;
			ray.m_vDirection.y = v.x * mInverseView.m01 + v.y * mInverseView.m11 + v.z * mInverseView.m21;
			ray.m_vDirection.z = v.x * mInverseView.m02 + v.y * mInverseView.m12 + v.z * mInverseView.m22;
			// 	 		//origin	=	m_vCurrentPosition;
			ray.m_vStart	=	Float3(mInverseView.m30,mInverseView.m31,mInverseView.m32);
			//Ray ray;
			ray.m_vDirection.Normalize();

			return	ray;
#else
			Matrix inverseVP = m_matViewProj;
			inverseVP.Inverse();

			Real nx = (2.0f * x) - 1.0f;
			Real ny = 1.0f - (2.0f * y);
			// Use midPoint rather than far point to avoid issues with infinite projection
			Float3 midPoint (nx, ny,  0.0f);

			// Get ray origin and ray target on near plane in world space
			Float3 rayTarget;


			rayTarget = inverseVP * midPoint;

			Float3 rayDirection = rayTarget - GetPosition();
			rayDirection.Normalize();

			return	Ray(GetPosition(),rayDirection);
#endif
			
		}
Beispiel #4
0
	void MeshGroup::_genMesh(const Array<Mesh *> & arr, int first, int last, bool hasLightingColor)
	{
		MeshSourcePtr source = arr[0]->GetSource();
		Mesh * mesh = new Mesh;

		for (int i = 0; i < source->GetMeshBufferCount(); ++i)
		{
			SubMesh * submesh = mesh->NewSubMesh();
			VertexBufferPtr srcVB = source->GetMeshBuffer(i)->GetRenderOp()->vertexBuffers[0];
			IndexBufferPtr srcIB = source->GetMeshBuffer(i)->GetRenderOp()->indexBuffer;
			int p_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::POSITION);
			int n_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::NORMAL);
			int stride = srcVB->GetStride();

			VertexBufferPtr vb = HWBufferManager::Instance()->NewVertexBuffer(stride, srcVB->GetCount() * (last - first));
			
			const char * v_src = (const char *)srcVB->Lock(eLockFlag::READ);
			char * v_dest = (char *)vb->Lock(eLockFlag::WRITE);
			for (int j = first; j < last; ++j)
			{
				const Mat4 & worldTM = arr[j]->GetWorldTM();
				bool hasScale = arr[j]->GetWorldScale() != Float3(1, 1, 1);

				for (int k = 0; k < srcVB->GetCount(); ++k)
				{
					memcpy(v_dest, v_src, stride);

					Float3 * position = (Float3 *)(v_dest + p_offset);
					position->TransformA(worldTM);
					
					if (n_offset != -1)
					{
						Float3 * normal = (Float3 *)(v_dest + n_offset);
						normal->TransformN(worldTM);

						if (hasScale)
						{
							normal->Normalize();
						}
					}

					v_dest += stride;
					v_src += stride;
				}
			}
			vb->Unlock();
			srcVB->Unlock();

			IndexBufferPtr ib = HWBufferManager::Instance()->NewIndexBuffer(srcIB->GetCount() * (last - first));

			int startVertex = 0;
			const short * i_src = (const short *)srcIB->Lock(eLockFlag::READ);
			char * i_dest = (char *)ib->Lock(eLockFlag::WRITE);
			for (int j = first; j < last; ++j)
			{
				for (int k = 0; k < srcIB->GetCount(); ++k)
				{
					*i_dest++ = (*i_src++) + startVertex;
				}

				startVertex += srcVB->GetCount();
			}
			ib->Unlock();
			srcIB->Unlock();
			
			submesh->GetRenderOp()->vertexDeclarations[0] = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0];
			submesh->GetRenderOp()->vertexBuffers[0] = vb;
			submesh->GetRenderOp()->indexBuffer = ib;
			submesh->GetRenderOp()->primCount = ib->GetCount() / 3;
			submesh->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST;

			if (hasLightingColor)
			{
				int count = submesh->GetRenderOp()->vertexBuffers[0]->GetCount();
				submesh->GetRenderOp()->vertexDeclarations[LIGHTING_COLOR_STREAM].AddElement(eVertexSemantic::LIGHTING_COLOR, eVertexType::UBYTE4);
				submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM] = HWBufferManager::Instance()->NewVertexBuffer(4, count);

				Array<Rgba32> lightColors;
				Rgba32 * data = (Rgba32 *)submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Lock(eLockFlag::WRITE);
				for (int j = first; j < last; ++j)
				{
					arr[j]->GetLightingColor(lightColors);
					d_assert (lightColors.Size() > 0);

					memcpy(data, &lightColors[0], 4 * count);

					startVertex += count;
					lightColors.Clear();
				}
				submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Unlock();
			}

			*submesh->GetMaterial() = *source->GetMeshBuffer(i)->GetMaterial();

			submesh->SetMeshShader(source->GetMeshBuffer(i)->GetShader());
		}

		mesh->SetSLMode(hasLightingColor ? eStaticLightingMode::LIGHTING_COLOR : eStaticLightingMode::NONE);

		mMeshes.PushBack(mesh);
	}
		Air::Engine::enumMouseRayCastType ObjectController::ChangeType( const Float3& vStart,const Float3& vDir )
		{
			Float44 matWorldInv	=	m_WorldMatrix;
			matWorldInv.Inverse();
			Float3 vNewStart	= matWorldInv*vStart;
			Float3 vNewDir		=	matWorldInv*(vStart+vDir)	-	vNewStart;
			vNewDir.Normalize();

			float	fDistance	=	vStart.Distance(m_WorldMatrix.GetPosition())*0.1;

			//if(m_WorldBound.RayCast(vStart,vDir))
			{
				switch(m_ControlMode){
					case eMCM_Select:{

								 }break;
					case eMCM_Move:
					case eMCM_Scale:{
						BoundingBox AXIS[3];
						AXIS[0].vMin	=	Float3(0,-0.05,-0.05)*fDistance;
						AXIS[0].vMax	=	Float3(1,0.05,0.05)*fDistance;

						AXIS[1].vMin	=	Float3(-0.05,0,-0.05)*fDistance;
						AXIS[1].vMax	=	Float3(0.05,1,0.05)*fDistance;

						AXIS[2].vMin	=	Float3(-0.05,-0.05,0)*fDistance;
						AXIS[2].vMax	=	Float3(0.05,0.05,1)*fDistance;

						for(int i=0;i<3;i++){
							if(AXIS[i].RayCast(vNewStart,vNewDir)){
								m_RayCastType	=	enumMouseRayCastType(i+1);
#if 0
								char str[64];
								sprintf_s(str,"%d\n",m_RayCastType);
								OutputDebugStringA(str);
#endif
								break;
							}else{
								m_RayCastType	=	eMRCT_None;
							}
						}

								}break;
					case eMCM_Rotate:{
						BoundingBox AXIS[3];
						AXIS[0].vMin	=	Float3(-0.01,-1,-1)*fDistance;
						AXIS[0].vMax	=	Float3(0.01,1,1)*fDistance;

						AXIS[1].vMin	=	Float3(-1,-0.01,-1)*fDistance;
						AXIS[1].vMax	=	Float3(1,0.01,1)*fDistance;

						AXIS[2].vMin	=	Float3(-1,-1,-0.01)*fDistance;
						AXIS[2].vMax	=	Float3(1,1,0.01)*fDistance;

						float fDis[3]={10000,10000,10000};
						bool bHit	=	false;
						for(int i=0;i<3;i++){
							if(AXIS[i].RayCast(vNewStart,vNewDir,&fDis[i],NULL)){
								Float3 hitPos	=	vNewDir*fDis[i]+vNewStart;
								float dis	=	(hitPos.Distance(Float3(0,0,0)))/fDistance;
								if(dis < 1.0	&& dis > 0.8f){
									bHit	=	true;
								}else{
									fDis[i]	=	10000.0f;
								}
							}	
						}
						if(bHit){
							m_RayCastType	=	eMRCT_X;
							for(int i=1;i<3;i++){
								if(fDis[i]	<	fDis[0]){
									fDis[0]	=	fDis[i];
									m_RayCastType	=	enumMouseRayCastType(i+1);
								}
							}
#if 0
							char str[64];
							sprintf_s(str,"%d\n",m_RayCastType);
							OutputDebugStringA(str);
#endif

						}else{
							m_RayCastType	=	eMRCT_None;
						}
								 }break;
				}
			}

			return m_RayCastType;
		}
Beispiel #6
0
	void PS_Billboard::_getBillboardXYAxis(Float3 & xAxis, Float3 & yAxis, const Float3 & pos, const Float3 & dir)
	{
		int type = mParent->GetBillboardType();
		bool facing = mParent->IsAccurateFacing();

		switch (type)
		{
		case PS_BillboardType::POINT:
			if (facing)
			{
				Float3 vCamDir = pos - mCamPos;
				vCamDir.Normalize();

				yAxis = mCamYAxis;
				xAxis = Float3::Cross(yAxis, vCamDir);

				xAxis.Normalize();
			}
			else
			{
				xAxis = mCamXAxis;
				yAxis = mCamYAxis;
			}
			break;

		case PS_BillboardType::ORIENTED:
			if (facing)
			{
				Float3 vCamDir = pos - mCamPos;
				vCamDir.Normalize();

				yAxis = dir;
				xAxis = Float3::Cross(yAxis, vCamDir);

				xAxis.Normalize();
			}
			else
			{
				yAxis = dir;
				xAxis = Float3::Cross(yAxis, mCamZAxis);
				
				xAxis.Normalize();
			}
			break;

		case PS_BillboardType::ORIENTED_COMMON:
			if (facing)
			{
				Float3 vCamDir = pos - mCamPos;
				vCamDir.Normalize();

				yAxis = mCommonDir;
				xAxis = Float3::Cross(yAxis, vCamDir);

				xAxis.Normalize();
			}
			else
			{
				yAxis = mCommonDir;
				xAxis = Float3::Cross(yAxis, mCamZAxis);

				xAxis.Normalize();
			}
			break;

		case PS_BillboardType::PERPENDICULAR:
			{
				xAxis = Float3::Cross(mCommonUp, dir);
				yAxis = Float3::Cross(dir, xAxis);
				
				xAxis.Normalize();
				yAxis.Normalize();
			}
			break;

		case PS_BillboardType::PERPENDICULAR_COMMON:
			{
				xAxis = Float3::Cross(mCommonUp, mCommonDir);
				yAxis = mCommonDir;

				xAxis.Normalize();
			}
			break;
		}
	}