void RasNormalMap::DoPerVertexLighting( VertexBuffer& workingVB, FaceList& workingFaces, RenderObject& obj )
	{
		const VEC3& camPos = g_env.renderer->m_camera.GetPos().GetVec3();
		MAT44 matInvWorld = obj.m_matWorld.Inverse();

		for (size_t iVert=0; iVert<obj.m_verts.size(); ++iVert)
		{
			SVertex& vert = obj.m_verts[iVert];

			// Get the matrix which transforms vector from object space to tangent space
			MAT44 matTBN;
			matTBN.SetRow(0, VEC4(vert.tangent, 0));
			matTBN.SetRow(1, VEC4(vert.binormal, 0));
			matTBN.SetRow(2, VEC4(vert.normal, 0));

			// Calc light dir in object space
			const VEC3& lightDir = g_env.renderer->m_testLight.neg_dir;
			vert.lightDirTS = Common::Transform_Vec3_By_Mat44(lightDir, matInvWorld, false).GetVec3();
			// Transform!
			vert.lightDirTS = Common::Transform_Vec3_By_Mat44(vert.lightDirTS, matTBN, false).GetVec3();

			// Half-angle vector
			VEC3 eyeDir = Common::Sub_Vec3_By_Vec3(camPos, vert.pos.GetVec3());
			eyeDir.Normalize();
			Common::Add_Vec3_By_Vec3(vert.halfAngleTS, eyeDir, lightDir);
			vert.halfAngleTS.Normalize();
			vert.halfAngleTS = Common::Transform_Vec3_By_Mat44(vert.halfAngleTS, matTBN, false).GetVec3();
		}
	}
void CPlayerBase::UpdateCinematic(float elapsed) {
	static float time_out = 2.f;
	time_out -= getDeltaTime();
	TCompTransform* player_transform = myEntity->get<TCompTransform>();
	float yaw, pitch;
	transform->getAngles(&yaw, &pitch);
	float dist = simpleDistXZ(cc->GetPosition(), cinematicTargetPos);
	if (dist < epsilonPos || time_out <= 0.f) {
		if (time_out <= 0.f) cc->teleport(cinematicTargetPos);
		time_out = 2.f;
		// Reach position
		float deltaYaw = cinematicTargetYaw - yaw;
		if (abs(deltaYaw) < epsilonYaw) {
			//In position and Oriented
			onCinematic = false;
			logic_manager->throwUserEvent(cinematicEndCode);
			ChangeCommonState("idle");
		}
		else {
			//Orientation to target
			transform->setAngles(yaw * 0.9f + 0.1f * cinematicTargetYaw, pitch);
		}
	}
	else {
		// Go to target
		float deltaYaw = transform->getDeltaYawToAimTo(cinematicTargetPos);
		if (deltaYaw > epsilonYaw) transform->setAngles(yaw + 0.1f * deltaYaw, pitch);
		VEC3 dir = cinematicTargetPos - cc->GetPosition();
		dir.y = 0;
		dir.Normalize();
		cc->AddMovement(dir, player_max_speed * getDeltaTime());
		moving = true;
		ChangeCommonState("moving");
	}
}
Exemplo n.º 3
0
bool interLineSeg(const VEC3& A, const VEC3& AB, typename VEC3::DATA_TYPE AB2,
				  const VEC3& P, const VEC3& Q, VEC3& inter)
{
#define EPSILON (1.0e-5)
	typedef typename VEC3::DATA_TYPE T ;

	T dist = Geom::distancePoint2TrianglePlane(AB-A,A,P,Q);

//	std::cout << "dist "<<  dist << std::endl;

	if (dist>EPSILON)
		return false;

	VEC3 AP = P - A ;
	VEC3 PQ = Q - P ;
	T X = AB * PQ ;
	T beta = ( AB2 * (AP*PQ) - X * (AP*AB) ) / ( X*X - AB2 * PQ.norm2() ) ;

//	std::cout << "beta "<<  beta << std::endl;

	if ((beta<0.0) || (beta>1.0))
		return false;

	inter = beta*Q +(1.0-beta)*P;
	return true;
#undef EPSILON
}
Exemplo n.º 4
0
	//-------------------------------------------------------------------------------
	void Renderer::Update(float dt)
	{
		static DWORD nFrameCnt = 0;
		static float fFrameTime = 0;

		// Calc FPS
		++nFrameCnt;
		fFrameTime += dt;

		if (fFrameTime >= 1.0f)
		{
			g_env.pFrameStat->lastFPS = nFrameCnt / fFrameTime;
			nFrameCnt = 0;
			fFrameTime = 0;
		}

		// Update cBuffer
		m_cBufferGlobal.time = GetTickCount() / 1000.0f;

		Camera* cam = g_env.pSceneMgr->GetCamera();
		const MAT44& matView = cam->GetViewMatrix();
		const MAT44& matProj = cam->GetProjMatrix();

		m_cBufferGlobal.camPos = cam->GetPos();

		VEC3 vNegLight = g_env.pSceneMgr->GetSunLight().lightDir;
		vNegLight.Neg();
		vNegLight.Normalize();
		m_cBufferGlobal.lightDirection = vNegLight;

		m_cBufferGlobal.lightColor = g_env.pSceneMgr->GetSunLight().lightColor;
		m_cBufferGlobal.ambientColor.Set(0.2f, 0.2f, 0.2f);
		m_cBufferGlobal.nearZ = cam->GetNearClip();
		m_cBufferGlobal.farZ = cam->GetFarClip();
		m_cBufferGlobal.shadowMapTexelSize = 1.0f / g_env.pSceneMgr->GetShadowMapSize();
		m_cBufferGlobal.frameBufferSize[0] = m_wndWidth;
		m_cBufferGlobal.frameBufferSize[1] = m_wndHeight;
		m_cBufferGlobal.frameBufferSize[2] = m_cBufferGlobal.frameBufferSize[3] = 0;
		
		cam->GetFarCorner(m_cBufferGlobal.frustumFarCorner);

#if USE_PSSM
		ShadowMapPSSM* pPSSM = g_env.pSceneMgr->GetShadowMap()->GetPSSM();

		m_cBufferGlobal.matShadow[0] = pPSSM->GetShadowTransform(0).Transpose();
		m_cBufferGlobal.matShadow[1] = pPSSM->GetShadowTransform(1).Transpose();
		m_cBufferGlobal.matShadow[2] = pPSSM->GetShadowTransform(2).Transpose();
#else
		m_cBufferGlobal.matShadow[0] = g_env.pSceneMgr->GetShadowMap()->GetShadowTransform().Transpose();
#endif
		m_cBufferGlobal.matView = matView.Transpose();
		m_cBufferGlobal.matProj = matProj.Transpose();
		m_cBufferGlobal.matInvView = matView.Inverse().Transpose();
		m_cBufferGlobal.matViewProj = m_cBufferGlobal.matProj * m_cBufferGlobal.matView;

		UpdateGlobalCBuffer(true, true, true);
	}
Exemplo n.º 5
0
IK_IMPL_SOLVER(grabPilaIK, info, result) {
	GET_COMP(mole_t, info.handle, TCompTransform);
	GET_COMP(skc, info.handle, SkelControllerMole);
	GET_COMP(pila_t, skc->getGrabbedPila(), TCompTransform);
	VEC3 right = -mole_t->getLeft();
	right.Normalize();
	result.new_pos = pila_t->getPosition() + right * 0.3f;

	//result.bone_normal = skc->getGrabNormalLeft();
}
Exemplo n.º 6
0
/**
 * @brief computeLengthEdges
 * Demonstrate usage of 2 attributes on 2 differents orbits.
 * @param map the map
 * @param pos attribute handler of position of vertices
 * @param len attribute handler of length of edges
 */
void computeLengthEdges(MAP& map,const VertexAttribute<VEC3, MAP>& pos, EdgeAttribute<float, MAP> len)
{
	// warning c++11 lambda syntax
	foreach_cell<EDGE>(map,[&](Edge e) // for all edge e of map do
	{
		VEC3 P1 = pos[e.dart]; // access with dart because of access to VertexAttribute with an edge
		VEC3 P2 = pos[map.phi1(e)]; // phi1 return a dart so no problem (and e can auto-cast in dart)
		VEC3 V = P2 - P1;
		len[e] = V.norm();
	});
}
Exemplo n.º 7
0
void SimpleGMap2::cb_initGL()
{
	Utils::GLSLShader::setCurrentOGLVersion(1) ;

	Geom::BoundingBox<VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
	VEC3 gPosObj = bb.center() ;
	float tailleX = bb.size(0) ;
	float tailleY = bb.size(1) ;
	float tailleZ = bb.size(2) ;
	float gWidthObj = std::max<float>(std::max<float>(tailleX, tailleY), tailleZ) ;
	setParamObject(gWidthObj, gPosObj.data());
}
Exemplo n.º 8
0
	//---------------------------------------------------------------------
	void TerrainQuadTreeNode::mergeIntoBounds(long x, long y, const VEC3& pos)
	{
		if (pointIntersectsNode(x, y))
		{
			VEC3 localPos = pos - mLocalCentre;
			mAABB.Merge(localPos);
			mBoundingRadius = std::max(mBoundingRadius, localPos.GetLength());
			
			if (!isLeaf())
			{
				for (int i = 0; i < 4; ++i)
					mChildren[i]->mergeIntoBounds(x, y, pos);
			}
		}
	}
Exemplo n.º 9
0
void SimpleGMap3::cb_initGL()
{
    Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ;
    VEC3 gPosObj = bb.center() ;
    float tailleX = bb.size(0) ;
    float tailleY = bb.size(1) ;
    float tailleZ = bb.size(2) ;
    float gWidthObj = std::max<float>(std::max<float>(tailleX, tailleY), tailleZ) ;
    setParamObject(gWidthObj, gPosObj.data());

	m_render_topo = new Algo::Render::GL2::Topo3RenderGMap<PFP>();
    m_render_topo->setDartWidth(2.0f);
    m_render_topo->setInitialDartsColor(1.0f,1.0f,1.0f);
	m_render_topo->updateData(myMap, position, 0.9f,0.9f,0.8f);
}
void CPlayerBase::UpdateMoves()
{
	PROFILE_FUNCTION("update moves base");

	TCompTransform* player_transform = myEntity->get<TCompTransform>();
	VEC3 player_position = player_transform->getPosition();

	VEC3 direction = directionForward + directionLateral;

	CEntity * camera_e = camera;
	TCompTransform* camera_comp = camera_e->get<TCompTransform>();

	direction.Normalize();

	float yaw, pitch;
	camera_comp->getAngles(&yaw, &pitch);
	float new_x, new_z;

	new_x = direction.x * cosf(yaw) + direction.z*sinf(yaw);
	new_z = -direction.x * sinf(yaw) + direction.z*cosf(yaw);

	direction.x = new_x;
	direction.z = new_z;

	direction.Normalize();

	float new_yaw = player_transform->getDeltaYawToAimDirection(direction);
	clampAbs_me(new_yaw, player_rotation_speed * getDeltaTime());
	player_transform->getAngles(&yaw, &pitch);

	player_transform->setAngles(new_yaw + yaw, pitch);

	//Set current velocity with friction
	float drag = 2.5f*getDeltaTime();
	float drag_i = (1 - drag);

	if (moving) player_curr_speed = drag_i*player_curr_speed + drag*player_max_speed;
	else player_curr_speed = drag_i*player_curr_speed - drag*player_max_speed;

	if (player_curr_speed < 0) {
		player_curr_speed = 0.0f;
		directionForward = directionLateral = VEC3(0, 0, 0);
	}

	cc->AddMovement(direction, player_curr_speed*getDeltaTime());
	if (moving) UpdateMovingWithOther();
}
Exemplo n.º 11
0
Intersection intersectionLineTriangle(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter)
{
	typedef typename VEC3::DATA_TYPE T ;

	VEC3 u = Tb - Ta ;
	VEC3 v = Tc - Ta ;
	VEC3 n = u ^ v ;

	VEC3 w0 = P - Ta ;
    T a = -(n * w0) ;
    T b = (n * Dir) ;

#define PRECISION 1e-20
    if(fabs(b) < PRECISION)			//ray parallel to triangle
			return NO_INTERSECTION ;
#undef PRECISION

	T r = a / b ;
	Inter = P + r * Dir ;			// intersect point of ray and plane

    // is I inside T?
	T uu = u.norm2() ;
	T uv = u * v ;
	T vv = v.norm2() ;
	VEC3 w = Inter - Ta ;
	T wu = w * u ;
	T wv = w * v ;
	T D = (uv * uv) - (uu * vv) ;

    // get and test parametric coords
	T s = ((uv * wv) - (vv * wu)) / D ;
	if(s < T(0) || s > T(1))
		return NO_INTERSECTION ;
	T t = ((uv * wu) - (uu * wv)) / D ;
	if(t < T(0) || (s + t) > T(1))
        return NO_INTERSECTION ;

	if((s == T(0) || s == T(1)))
		if(t == T(0) || t == T(1))
			return VERTEX_INTERSECTION ;
		else
			return EDGE_INTERSECTION ;
	else if(t == T(0) || t == T(1))
			return EDGE_INTERSECTION ;

    return FACE_INTERSECTION ;
}
void CPlayerBase::renderInMenu()
{
	PROFILE_FUNCTION("render in menu base");
	VEC3 direction = directionForward + directionLateral + directionVertical;
	direction.Normalize();
	direction = direction + directionJump;

	TCompTransform* player_transform = myEntity->get<TCompTransform>();
	VEC3 player_position = player_transform->getPosition();

	ImGui::Text("NODE: %s\n", state.c_str());
	ImGui::Text("position: %.4f, %.4f, %.4f\n", player_position.x, player_position.y, player_position.z);
	ImGui::Text("direction: %.4f, %.4f, %.4f", direction.x, direction.y, direction.z);
	ImGui::Text("jump: %.5f", jspeed);
	ImGui::DragFloat("time_start_falling", &time_start_falling);
	ImGui::DragFloat("max_time_start_falling", &max_time_start_falling);
}
Exemplo n.º 13
0
bool intersectionSphereEdge(typename PFP::MAP& map, const typename PFP::VEC3& center, typename PFP::REAL radius, Edge e, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position, typename PFP::REAL& alpha)
{
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

	const VEC3& p1 = position[e.dart];
	const VEC3& p2 = position[map.phi1(e.dart)];
	if(Geom::isPointInSphere(p1, center, radius) && !Geom::isPointInSphere(p2, center, radius))
	{
		VEC3 p = p1 - center;
		VEC3 qminusp = p2 - center - p;
		REAL s = p * qminusp;
		REAL n2 = qminusp.norm2();
		alpha = (- s + sqrt(s*s + n2 * (radius*radius - p.norm2()))) / n2;
		return true ;
	}
	return false ;
}
	void RasGouraud::DoPerVertexLighting( VertexBuffer& workingVB, FaceList& workingFaces, RenderObject& obj )
	{
		///Gouraud shade基于逐顶点法线
		for (size_t iVert=0; iVert<workingVB.size(); ++iVert)
		{
			SVertex& vert = workingVB[iVert];

			if(!vert.bActive)
				continue;

			//在世界空间进行光照
			VEC3 worldNormal = Common::Transform_Vec3_By_Mat44(vert.normal, obj.m_matWorldIT, false).GetVec3();
			worldNormal.Normalize();

			SColor tmp;
			RenderUtil::DoLambertLighting(tmp, worldNormal, g_env.renderer->m_testLight.neg_dir, obj.m_pMaterial);
			vert.color *= tmp;
		}
	}
Exemplo n.º 15
0
Intersection intersectionSegmentHalfPlan(const VEC3& PA, const VEC3& PB,
		const VEC3& P, const VEC3& DirP, const VEC3& OrientP)//, VEC3& Inter)
{
	VEC3 NormP = (DirP-P) ^ (OrientP-P) ;
	NormP.normalize() ;

	//intersection SegmentPlan
	Intersection inter = intersectionSegmentPlan(PA,PB,P,NormP);
	if(inter == EDGE_INTERSECTION)
	{
		//and one of the two points must be in the right side of the line
		return intersectionSegmentPlan(PA,PB, P, OrientP);
	}
	else
	{
		return inter;
	}



}
Exemplo n.º 16
0
VEC3 operator* (const float scalar, VEC3& v)
{
    return(VEC3(scalar * v.x(), scalar * v.y(), scalar * v.z()));
}
Exemplo n.º 17
0
Intersection intersectionSegmentTriangle(const VEC3& PA, const VEC3& PB, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter)
{
	typedef typename VEC3::DATA_TYPE T ;
	const T precision = 0.0001;//std::numeric_limits<T>::min();

	VEC3 u = Tb - Ta ;
	VEC3 v = Tc - Ta ;
	VEC3 Dir = PB - PA ;

	VEC3 n = u ^ v ;

	VEC3 w0 = PA - Ta ;
    float a = -(n * w0) ;
    float b = (n * Dir) ;

    if(fabs(b) < precision)			//ray parallel to triangle
		return NO_INTERSECTION ;

	//compute intersection
	T r = a / b ;

	if((r < -precision) || (r > (T(1) + precision)))
		return NO_INTERSECTION;

	Inter = PA + r * Dir;			// intersect point of ray and plane

    // is I inside T?
	T uu = u.norm2() ;
	T uv = u * v ;
	T vv = v.norm2() ;
	VEC3 w = Inter - Ta ;
	T wu = w * u ;
	T wv = w * v ;
	T D = (uv * uv) - (uu * vv) ;

    // get and test parametric coords
	T s = ((uv * wv) - (vv * wu)) / D ;

	if(s <= precision)
		s = 0.0f;

	if(s < T(0) || s > T(1))
		return NO_INTERSECTION ;

	T t = ((uv * wu) - (uu * wv)) / D ;

	if(t <= precision)
		t = 0.0f;

	if(t < T(0) || (s + t) > T(1))
        return NO_INTERSECTION ;

	if((s == T(0) || s == T(1)))
		if(t == T(0) || t == T(1))
			return VERTEX_INTERSECTION ;
		else
			return EDGE_INTERSECTION ;
	else if(t == T(0) || t == T(1))
			return EDGE_INTERSECTION ;

    return FACE_INTERSECTION ;
}
Exemplo n.º 18
0
VEC3 cross(const VEC3& a, const VEC3& b)
{
    float x = (a.y()*b.z())-(b.y()*a.z());
    float y = (a.z()*b.x())-(b.z()*b.x());
    float z = (a.x()*b.y())-(b.x()*a.y());
    
    return (VEC3(x, y, z));
}
Exemplo n.º 19
0
	//---------------------------------------------------------------------
	bool TerrainQuadTreeNode::calculateCurrentLod(float cFactor)
	{
		mSelfOrChildRendered = false;

		// early-out
		/* disable this, could cause 'jumps' in LOD as children go out of frustum
		if (!cam->isVisible(mMovable->getWorldBoundingBox(true)))
		{
			mCurrentLod = -1;
			return mSelfOrChildRendered;
		}
		*/

		// Check children first
		int childRenderedCount = 0;
		if (!isLeaf())
		{
			for (int i = 0; i < 4; ++i)
			{
				if (mChildren[i]->calculateCurrentLod(cFactor))
					++childRenderedCount;
			}

		}

		if (childRenderedCount == 0)
		{

			// no children were within their LOD ranges, so we should consider our own
			VEC3 localPos = g_env.pSceneMgr->GetCamera()->GetPos() - mLocalCentre - mTerrain->getPosition();
			float dist;
			if (g_env.pSceneMgr->GetTerrainOptions()->getUseRayBoxDistanceCalculation())
			{
				// Get distance to this terrain node (to closest point of the box)
				// head towards centre of the box (note, box may not cover mLocalCentre because of height)
				//VEC3 dir(mAABB.getCenter() - localPos);
				//dir.normalise();
				//Ray ray(localPos, dir);
				//std::pair<bool, float> intersectRes = Math::intersects(ray, mAABB);

				//// ray will always intersect, we just want the distance
				//dist = intersectRes.second;
				_AST(0);
			}
			else
			{
				// distance to tile centre
				dist = localPos.GetLength();
				// deduct half the radius of the box, assume that on average the 
				// worst case is best approximated by this
				dist -= (mBoundingRadius * 0.5f);
			}

			// For each LOD, the distance at which the LOD will transition *downwards*
			// is given by 
			// distTransition = maxDelta * cFactor;
			uint32 lodLvl = 0;
			mCurrentLod = -1;
			for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i, ++lodLvl)
			{
				// If we have no parent, and this is the lowest LOD, we always render
				// this is the 'last resort' so to speak, we always enoucnter this last
				if (lodLvl+1 == mLodLevels.size() && !mParent)
				{
					mCurrentLod = lodLvl;
					mSelfOrChildRendered = true;
					mLodTransition = 0;
				}
				else
				{
					// check the distance
					LodLevel* ll = *i;

					// Calculate or reuse transition distance
					float distTransition;
					if (Common::Equal(cFactor, ll->lastCFactor))
						distTransition = ll->lastTransitionDist;
					else
					{
						distTransition = ll->maxHeightDelta * cFactor;
						ll->lastCFactor = cFactor;
						ll->lastTransitionDist = distTransition;
					}

					if (dist < distTransition)
					{
						// we're within range of this LOD
						mCurrentLod = lodLvl;
						mSelfOrChildRendered = true;

						if (mTerrain->_getMorphRequired())
						{
							// calculate the transition percentage
							// we need a percentage of the total distance for just this LOD, 
							// which means taking off the distance for the next higher LOD
							// which is either the previous entry in the LOD list, 
							// or the largest of any children. In both cases these will
							// have been calculated before this point, since we process
							// children first. Distances at lower LODs are guaranteed
							// to be larger than those at higher LODs

							float distTotal = distTransition;
							if (isLeaf())
							{
								// Any higher LODs?
								if (i != mLodLevels.begin())
								{
									LodLevelList::iterator prev = i - 1;
									distTotal -= (*prev)->lastTransitionDist;
								}
							}
							else
							{
								// Take the distance of the lowest LOD of child
								const LodLevel* childLod = mChildWithMaxHeightDelta->getLodLevel(
									mChildWithMaxHeightDelta->getLodCount()-1);
								distTotal -= childLod->lastTransitionDist;
							}
							// fade from 0 to 1 in the last 25% of the distance
							float distMorphRegion = distTotal * 0.25f;
							float distRemain = distTransition - dist;

							mLodTransition = 1.0f - (distRemain / distMorphRegion);
							mLodTransition = std::min(1.0f, mLodTransition);
							mLodTransition = std::max(0.0f, mLodTransition);

							// Pass both the transition % and target LOD (GLOBAL current + 1)
							// this selectively applies the morph just to the
							// vertices which would drop out at this LOD, even 
							// while using the single shared vertex data
							mTerrain->m_cbTerrain.lodMorph = VEC2(mLodTransition, mCurrentLod + mBaseLod + 1);
						}
						// since LODs are ordered from highest to lowest detail, 
						// we can stop looking now
						break;
					}

				}
			}

		}
		else 
		{
			// we should not render ourself
			mCurrentLod = -1;
			mSelfOrChildRendered = true; 
			if (childRenderedCount < 4)
			{
				// only *some* children decided to render on their own, but either 
				// none or all need to render, so set the others manually to their lowest
				for (int i = 0; i < 4; ++i)
				{
					TerrainQuadTreeNode* child = mChildren[i];
					if (!child->isSelfOrChildRenderedAtCurrentLod())
					{
						child->setCurrentLod(child->getLodCount()-1);
						child->setLodTransition(1.0);
					}
				}
			} // (childRenderedCount < 4)

		} // (childRenderedCount == 0)


		return mSelfOrChildRendered;

	}