Example #1
0
void msimulator_Simulate( Fvector& result, Fvector& start, Fvector& end, float _radius, float _height)
{
    SCollisionData	cl_data;
    float			half_height	= _height/2;

    // Calc BB
    Fbox			b1,b2,bb;
    create_bb		(b1,start,	_radius,_height);
    create_bb		(b2,end,	_radius,_height);
    bb.merge		(b1,b2);
    bb.grow			(0.05f);

    // Collision query
    Fvector			bbC,bbD;
    bb.get_CD		(bbC,bbD);
    XRC.box_options	(0);
    XRC.box_query	(&Level,bbC,bbD);

    // XForm everything to ellipsoid space
    Fvector			xf;
    xf.set			(1/_radius,1/half_height,1/_radius);

    Fvector			Lposition;
    Lposition.set	(start);
    Lposition.y		+= half_height;
    Lposition.mul	(xf);

    Fvector			target;
    target.set		(end);
    target.y		+= half_height;
    target.mul		(xf);

    Fvector			Lvelocity;
    Lvelocity.sub	(end,start);
    Lvelocity.mul	(xf);

    cl_data.vLastSafePosition.set	(Lposition);

    // Get the data for the triangles in question and scale to ellipsoid space
    int tri_count			= XRC.r_count();
    clContactedT.resize		(tri_count);
    if (tri_count) {
        Fvector vel_dir;
        vel_dir.normalize_safe	(Lvelocity);
        for (int i_t=0; i_t<tri_count; i_t++) {
            cl_tri& T			= clContactedT[i_t];
            CDB::RESULT&		rp = XRC.r_begin()[i_t];
//			CDB::TRI&	O		=
            *(Level.get_tris()+rp.id);

            T.p[0].mul			(rp.verts[0],xf);
            T.p[1].mul			(rp.verts[1],xf);
            T.p[2].mul			(rp.verts[2],xf);
            T.N.mknormal		(T.p[0],T.p[1],T.p[2]);

            T.d = -T.N.dotproduct(T.p[0]);
            T.e10.sub(T.p[1],T.p[0]);
            T.e10s = T.e10.magnitude();
            T.e10.div(T.e10s);
            T.e21.sub(T.p[2],T.p[1]);
            T.e21s = T.e21.magnitude();
            T.e21.div(T.e21s);
            T.e02.sub(T.p[0],T.p[2]);
            T.e02s = T.e02.magnitude();
            T.e02.div(T.e02s);
        }
    }

    // call the recursive collision response function
    Fvector POS;

    for (int i=0; i<3; i++) {
        POS.set(msimulator_CollideWithWorld(cl_data, Lposition, Lvelocity, 0));
        if (fsimilar(POS.x,target.x)&&fsimilar(POS.z,target.z)) break;

        Lposition.set	(POS);
        Lvelocity.sub	(target,POS);
        Lvelocity.y		= 0;
    }

    result.div(POS,xf);
    result.y-=half_height;
}
void CLevelGraph::choose_point(const Fvector &start_point, const Fvector &finish_point, const SContour &_contour, int node_id, Fvector &temp_point, int &saved_index) const
{
	SContour					tNextContour;
	SSegment					tNextSegment;
	Fvector						tCheckPoint1 = start_point, tCheckPoint2 = start_point, tIntersectPoint;
	contour						(tNextContour,node_id);
	intersect					(tNextSegment,tNextContour,_contour);
	u32							dwIntersect = intersect(start_point.x,start_point.z,finish_point.x,finish_point.z,tNextSegment.v1.x,tNextSegment.v1.z,tNextSegment.v2.x,tNextSegment.v2.z,&tIntersectPoint.x,&tIntersectPoint.z);
	if (!dwIntersect)
		return;
	for (int i=0; i<4; ++i) {
		switch (i) {
			case 0 : {
				tCheckPoint1	= tNextContour.v1;
				tCheckPoint2	= tNextContour.v2;
				break;
					 }
			case 1 : {
				tCheckPoint1	= tNextContour.v2;
				tCheckPoint2	= tNextContour.v3;
				break;
					 }
			case 2 : {
				tCheckPoint1	= tNextContour.v3;
				tCheckPoint2	= tNextContour.v4;
				break;
					 }
			case 3 : {
				tCheckPoint1	= tNextContour.v4;
				tCheckPoint2	= tNextContour.v1;
				break;
					 }
			default : NODEFAULT;
		}
		dwIntersect				= intersect(start_point.x,start_point.z,finish_point.x,finish_point.z,tCheckPoint1.x,tCheckPoint1.z,tCheckPoint2.x,tCheckPoint2.z,&tIntersectPoint.x,&tIntersectPoint.z);
		if (dwIntersect == LevelGraph::eLineIntersectionIntersect) {
			if (finish_point.distance_to_xz(tIntersectPoint) < finish_point.distance_to_xz(temp_point) + EPS_L) {
				temp_point = tIntersectPoint;
				saved_index = node_id;
			}
		}
		else
			if (dwIntersect == LevelGraph::eLineIntersectionEqual) {
				if (start_point.distance_to_xz(tCheckPoint1) > start_point.distance_to_xz(temp_point))
					if (start_point.distance_to_xz(tCheckPoint1) > start_point.distance_to_xz(tCheckPoint2)) {
						temp_point = tCheckPoint1;
						saved_index = node_id;
					}
					else {
						temp_point = tCheckPoint2;
						saved_index = node_id;
					}
				else
					if (start_point.distance_to_xz(tCheckPoint2) > start_point.distance_to_xz(temp_point)) {
						temp_point = tCheckPoint2;
						saved_index = node_id;
					}

			}
	}
}
Example #3
0
void CCustomObject::AnimationCreateKey(float t)
{
    Fvector R;		R.set(-PRotation.x,-PRotation.y,-PRotation.z);
    m_Motion->CreateKey(t,PPosition,R);
}
Example #4
0
void ComputeCylinder(Fcylinder& C, Fobb& B, FvectorVec& V)
{
    if (V.size()<3) 	{ C.invalidate(); return; }
    // pow(area,(3/2))/volume
    // 2*Pi*R*H+2*Pi*R*R
	
//	Fvector axis;
    float max_hI   	= flt_min;
    float min_hI   	= flt_max;
    float max_rI   	= flt_min;
    float max_hJ   	= flt_min;
    float min_hJ   	= flt_max;
    float max_rJ   	= flt_min;
    float max_hK   	= flt_min;
    float min_hK   	= flt_max;
    float max_rK   	= flt_min;
    Fvector axisJ 		= B.m_rotate.j;
    Fvector axisI 		= B.m_rotate.i;
    Fvector axisK 		= B.m_rotate.k;
    Fvector& c			= B.m_translate;
    for (FvectorIt I=V.begin(); I!=V.end(); I++){
        Fvector tmp;
    	Fvector pt		= *I;
    	Fvector pt_c;	pt_c.sub(pt,c);

    	float pI		= axisI.dotproduct(pt);
        min_hI			= _min(min_hI,pI);
        max_hI			= _max(max_hI,pI);
        tmp.mad			(c,axisI,axisI.dotproduct(pt_c));
        max_rI			= _max(max_rI,tmp.distance_to(pt));
        
    	float pJ		= axisJ.dotproduct(pt);
        min_hJ			= _min(min_hJ,pJ);
        max_hJ			= _max(max_hJ,pJ);
        tmp.mad			(c,axisJ,axisJ.dotproduct(pt_c));
        max_rJ			= _max(max_rJ,tmp.distance_to(pt));

    	float pK		= axisK.dotproduct(pt);
        min_hK			= _min(min_hK,pK);
        max_hK			= _max(max_hK,pK);
        tmp.mad			(c,axisK,axisK.dotproduct(pt_c));
        max_rK			= _max(max_rK,tmp.distance_to(pt));
    }

    float hI			= (max_hI-min_hI);
    float hJ			= (max_hJ-min_hJ);
    float hK			= (max_hK-min_hK);
    float vI			= hI*M_PI*_sqr(max_rI);
    float vJ			= hJ*M_PI*_sqr(max_rJ);
    float vK			= hK*M_PI*_sqr(max_rK);
//    vI					= pow(2*M_PI*max_rI*hI+2*M_PI*_sqr(max_rI),3/2)/vI;
//    vJ					= pow(2*M_PI*max_rJ*hJ+2*M_PI*_sqr(max_rJ),3/2)/vJ;
//    vK					= pow(2*M_PI*max_rK*hK+2*M_PI*_sqr(max_rK),3/2)/vK;
    // pow(area,(3/2))/volume
    // 2*Pi*R*H+2*Pi*R*R
    
    if (vI<vJ){
    	if (vI<vK){
        	//vI;
            C.m_direction.set	(axisI);
            C.m_height			= hI;
            C.m_radius			= max_rI;
        }else{
        	// vK
            C.m_direction.set	(axisK);
            C.m_height			= hK;
            C.m_radius			= max_rK;
        }
    }else {
        //vJ < vI
     	if (vJ<vK){
        	// vJ
            C.m_direction.set	(axisJ);
            C.m_height			= hJ;
            C.m_radius			= max_rJ;
        } else {
            //vK
            C.m_direction.set	(axisK);
            C.m_height			= hK;
            C.m_radius			= max_rK;
        }
    }
    
    C.m_center.set		(B.m_translate);
/*
    if (V.size()<3) { B.invalidate(); return; }
    Mgc::Cylinder CYL	= Mgc::ContCylinder(V.size(), (const Mgc::Vector3*) V.begin());
    B.m_center.set		(CYL.Center());
    B.m_direction.set	(CYL.Direction());
    B.m_height			= CYL.Height();
    B.m_radius			= CYL.Radius();
*/
}
Example #5
0
void xrBuildNodes()
{
	// begin
	XRC.box_options	(CDB::OPT_FULL_TEST);
	XRC.ray_options	(CDB::OPT_CULL | CDB::OPT_ONLYNEAREST);
	g_nodes.reserve	(1024*1024);

	// Initialize hash
	hash_Initialize ();

	for (u32 em=0; em<Emitters.size(); em++) 
	{
		// Align emitter
		Fvector			Pos = Emitters[em];
		SnapXZ			(Pos);
		Pos.y			+=1;
		Fvector			Dir; Dir.set(0,-1,0);
		
		XRC.ray_query	(&Level,Pos,Dir,3);
		if (XRC.r_count()==0) {
			Msg		("Can't align emitter");
			abort	();
		} else {
			CDB::RESULT& R = *XRC.r_begin();
			Pos.y = Pos.y - R.range;
		}
		
		// Build first node
		int oldcount = g_nodes.size();
		int start = BuildNode		(Pos,Pos);
		if (start==InvalidNode)		continue;
		if (start<oldcount)			continue;

		// Estimate nodes
		Fvector	LevelSize;
		LevelBB.getsize				(LevelSize);
		u32	estimated_nodes		= iFloor(LevelSize.x/g_params.fPatchSize)*iFloor(LevelSize.z/g_params.fPatchSize);
		
		// General cycle
		for (u32 i=0; i<g_nodes.size(); i++)
		{
			// left 
			if (g_nodes[i].n1==UnkonnectedNode)
			{
				Pos.set			(g_nodes[i].Pos);
				Pos.x			-=	g_params.fPatchSize;
				int	id			=	BuildNode(g_nodes[i].Pos,Pos);
				g_nodes[i].n1	=	id;
			}
			// fwd
			if (g_nodes[i].n2==UnkonnectedNode)
			{
				Pos.set			(g_nodes[i].Pos);
				Pos.z			+=	g_params.fPatchSize;
				int id			=	BuildNode(g_nodes[i].Pos,Pos);
				g_nodes[i].n2	=	id;
			}
			// right
			if (g_nodes[i].n3==UnkonnectedNode)
			{
				Pos.set			(g_nodes[i].Pos);
				Pos.x			+=	g_params.fPatchSize;
				int id			=	BuildNode(g_nodes[i].Pos,Pos);
				g_nodes[i].n3	=	id;
			}
			// back
			if (g_nodes[i].n4==UnkonnectedNode)
			{
				Pos.set			(g_nodes[i].Pos);
				Pos.z			-=	g_params.fPatchSize;
				int	id			=	BuildNode(g_nodes[i].Pos,Pos);
				g_nodes[i].n4	=	id;
			}
			if (i%512==0) {
				Status("%d / %d nodes created.",g_nodes.size()-i,g_nodes.size());

				float	p1	= float(i)/float(g_nodes.size());
				float	p2	= float(g_nodes.size())/estimated_nodes;
				float	p	= 0.1f*p1+0.9f*p2;

				clamp	(p,0.f,1.f);
				Progress(p);
			}
		}
	}
	Msg("Freeing memory...");
	hash_Destroy	();
}
int ESceneAIMapTools::BuildNodes(const Fvector& pos, int sz, bool bIC)
{
    // Align emitter
    Fvector			Pos = pos;
    SnapXZ			(Pos,m_Params.fPatchSize);
    Pos.y			+= 1;
    Fvector			Dir; Dir.set(0,-1,0);

	int cnt			= 0;		
    if (m_CFModel)	cnt=Scene->RayQuery(PQ,Pos,Dir,3,CDB::OPT_ONLYNEAREST|CDB::OPT_CULL,m_CFModel);
    else			cnt=Scene->RayQuery(PQ,Pos,Dir,3,CDB::OPT_ONLYNEAREST|CDB::OPT_CULL,GetSnapList());
    if (0==cnt) {
        ELog.Msg	(mtInformation,"Can't align position.");
        return		0;
    } else {
        Pos.y 		= Pos.y - PQ.r_begin()->range;
    }
		
    // Build first node
    int oldcount 	= m_Nodes.size();
    SAINode* start 	= BuildNode(Pos,Pos,bIC);
    if (!start)		return 0;

    // Estimate nodes
    float estimated_nodes	= (2*sz-1)*(2*sz-1);

	SPBItem* pb 	= 0;
    if (estimated_nodes>1024) pb = UI->ProgressStart(1, "Building nodes...");
    float radius			= sz*m_Params.fPatchSize-EPS_L;
    // General cycle
    for (int k=0; k<(int)m_Nodes.size(); k++){
        SAINode* N 			= m_Nodes[k];
        // left 
        if (0==N->n1){
            Pos.set			(N->Pos);
            Pos.x			-=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n1		=	BuildNode(N->Pos,Pos,bIC);
        }
        // fwd
        if (0==N->n2){
            Pos.set			(N->Pos);
            Pos.z			+=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n2		=	BuildNode(N->Pos,Pos,bIC);
        }
        // right
        if (0==N->n3){
            Pos.set			(N->Pos);
            Pos.x			+=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n3		=	BuildNode(N->Pos,Pos,bIC);
        }
        // back
        if (0==N->n4){
            Pos.set			(N->Pos);
            Pos.z			-=	m_Params.fPatchSize;
            if (Pos.distance_to(start->Pos)<=radius)
	            N->n4		=	BuildNode(N->Pos,Pos,bIC);
        }
        if (estimated_nodes>1024){
            if (k%128==0) {
                float	p1	= float(k)/float(m_Nodes.size());
                float	p2	= float(m_Nodes.size())/estimated_nodes;
                float	p	= 0.1f*p1+0.9f*p2;

                clamp	(p,0.f,1.f);
                pb->Update(p);
                // check need abort && redraw
                if (UI->NeedAbort()) break;
            }
        }
    }
	if (estimated_nodes>1024) UI->ProgressEnd(pb);
    return oldcount-m_Nodes.size();
}
Example #7
0
void		CTeleWhirlwindObject::		raise					(float step)
{

		CPhysicsShell*	p					=	get_object()	->PPhysicsShell();
	
		if(!p||!p->isActive())	
			return;
		else
			{
				p->SetAirResistance(0.f,0.f);
				p->set_ApplyByGravity(TRUE);
			}
		u16				element_number		=	p				->get_ElementsNumber();
		Fvector			center				=	m_telekinesis	->Center();
		CPhysicsElement* maxE=p->get_ElementByStoreOrder(0);
		for(u16 element=0;element<element_number;++element)
		{
			float k=strength;//600.f;
			float predict_v_eps=0.1f;
			float mag_eps	   =.01f;

			CPhysicsElement* E=	p->get_ElementByStoreOrder(element);
			if(maxE->getMass()<E->getMass())	maxE=E;
			if (!E->isActive()) continue;
			Fvector pos=E->mass_Center();

			Fvector diff;
			diff.sub(center,pos);
			float mag=_sqrt(diff.x*diff.x+diff.z*diff.z);
			Fvector lc;lc.set(center);
			if(mag>1.f)
			{
				lc.y/=mag;
			}
			diff.sub(lc,pos);
			mag=diff.magnitude();
			float accel=k/mag/mag/mag;//*E->getMass()
			Fvector dir;
			if(mag<mag_eps)
			{
				accel=0.f;
				//Fvector zer;zer.set(0,0,0);
				//E->set_LinearVel(zer);
				dir.random_dir();
			}
			else
			{
				dir.set(diff);dir.mul(1.f/mag);
			}
			Fvector vel;
			E->get_LinearVel(vel);
			float delta_v=accel*fixed_step;
			Fvector delta_vel; delta_vel.set(dir);delta_vel.mul(delta_v);
			Fvector predict_vel;predict_vel.add(vel,delta_vel);
			Fvector delta_pos;delta_pos.set(predict_vel);delta_pos.mul(fixed_step);
			Fvector predict_pos;predict_pos.add(pos,delta_pos);
			
			Fvector predict_diff;predict_diff.sub(lc,predict_pos);
			float predict_mag=predict_diff.magnitude();
			float predict_v=predict_vel.magnitude();

			Fvector force;force.set(dir);
			if(predict_mag>mag && predict_vel.dotproduct(dir)>0.f && predict_v>predict_v_eps)
			{
	
				Fvector motion_dir;motion_dir.set(predict_vel);motion_dir.mul(1.f/predict_v);
				float needed_d=diff.dotproduct(motion_dir);
				Fvector needed_diff;needed_diff.set(motion_dir);needed_diff.mul(needed_d);
				Fvector nearest_p;nearest_p.add(pos,needed_diff);//
				Fvector needed_vel;needed_vel.set(needed_diff);needed_vel.mul(1.f/fixed_step);
				force.sub(needed_vel,vel);
				force.mul(E->getMass()/fixed_step);
			}
			else
			{
				force.mul(accel*E->getMass());
			}
			
			
			E->applyForce(force.x,force.y+get_object()->EffectiveGravity()*E->getMass(),force.z);
		}
		Fvector dist;dist.sub(center,maxE->mass_Center());
		if(dist.magnitude()<m_telekinesis->keep_radius()&&b_destroyable)
		{
			p->setTorque(Fvector().set(0,0,0));
			p->setForce(Fvector().set(0,0,0));
			p->set_LinearVel(Fvector().set(0,0,0));
			p->set_AngularVel(Fvector().set(0,0,0));
			switch_state(TS_Keep);
		}
}
Example #8
0
void	CPHCharacter::getForce(Fvector& force)
{
	if(!b_exist)return;
	force.set(*(Fvector*)dBodyGetForce(m_body));
}
Example #9
0
void character_hit_animation_controller::PlayHitMotion( const Fvector &dir, const Fvector &bone_pos, u16 bi, CEntityAlive &ea )const
{
	IRenderVisual *pV = ea.Visual( );
	IKinematicsAnimated* CA = smart_cast<IKinematicsAnimated*>( pV );
	IKinematics* K = smart_cast<IKinematics*>( pV );
	
	//play_cycle(CA,all_shift_down,1,block_times[6],1) ;
	if( !( K->LL_BoneCount( ) > bi ) )
		return;

	Fvector dr = dir;
	Fmatrix m;
	GetBaseMatrix( m, ea );

#ifdef DEBUG
	if( ph_dbg_draw_mask1.test( phDbgHitAnims ) )
	{
		DBG_OpenCashedDraw();
		DBG_DrawLine( m.c, Fvector( ).sub( m.c, Fvector( ).mul( dir, 1.5 ) ), D3DCOLOR_XRGB( 255, 0, 255 ) );
		DBG_ClosedCashedDraw( 1000 );
	}
#endif

	m.invert( );
	m.transform_dir( dr );
//
	Fvector hit_point;
	K->LL_GetTransform( bi ).transform_tiny( hit_point, bone_pos );
	ea.XFORM( ).transform_tiny( hit_point );
	m.transform_tiny( hit_point );
	Fvector torqu;		
	torqu.crossproduct( dr, hit_point );
	hit_point.x = 0;


	float rotational_ammount = hit_point.magnitude( ) * g_params.power_factor * g_params.rotational_power_factor;//_abs(torqu.x)
	
	if( torqu.x < 0 )
		play_cycle( CA, hit_downr, 3, block_blends[7], 1 ) ;
	else
		play_cycle( CA, hit_downl, 3, block_blends[6], 1 ) ;

	if( !IsEffected( bi, *K ) )
		return;
	if( torqu.x<0 )
		play_cycle( CA, turn_right, 2, block_blends[4], rotational_ammount ) ;
	else
		play_cycle( CA, turn_left, 2, block_blends[5], rotational_ammount ) ;

	//CA->LL_SetChannelFactor(3,rotational_ammount);

	dr.x = 0;
	dr.normalize_safe();


	dr.mul(g_params.power_factor);
	if( dr.y > g_params.side_sensitivity_threshold )
		play_cycle( CA, rthit_motion, 2, block_blends[0], _abs( dr.y ) ) ;
	else if( dr.y < -g_params.side_sensitivity_threshold )
		play_cycle( CA, lthit_motion, 2, block_blends[1], _abs( dr.y ) ) ;

	if( dr.z<0.f )
		play_cycle( CA, fvhit_motion, 2, block_blends[2], _abs(dr.z) ) ;
	else
		play_cycle( CA, bkhit_motion, 2, block_blends[3], _abs( dr.z ) ) ;

	CA->LL_SetChannelFactor( 2, g_params.anim_channel_factor );


}
Example #10
0
void CPHCharacter::GetSavedVelocity(Fvector& vvel)
{
	
	if(IsEnabled())vvel.set(m_safe_velocity);
	else GetVelocity(vvel);
}
Example #11
0
void			CPHCharacter::get_AngularVel		( Fvector& velocity )		const		
{
	velocity.set(0,0,0);
}
Example #12
0
void dbg_draw_frustum	(float FOV, float _FAR, float A, Fvector &P, Fvector &D, Fvector &U)
{
    //if (!bDebug)		return;

    float YFov	= deg2rad(FOV*A);
    float XFov	= deg2rad(FOV);

    // calc window extents in camera coords
    float wR=tanf(XFov*0.5f);
    float wL=-wR;
    float wT=tanf(YFov*0.5f);
    float wB=-wT;

    // calc x-axis (viewhoriz) and store cop
    // here we are assuring that vectors are perpendicular & normalized
    Fvector			R,COP;
    D.normalize		();
    R.crossproduct	(D,U);
    R.normalize		();
    U.crossproduct	(R,D);
    U.normalize		();
    COP.set			(P);

    // calculate the corner vertices of the window
    Fvector			sPts[4];  // silhouette points (corners of window)
    Fvector			Offset,T;
    Offset.add		(D,COP);

    sPts[0].mul(R,wR);
    T.mad(Offset,U,wT);
    sPts[0].add(T);
    sPts[1].mul(R,wL);
    T.mad(Offset,U,wT);
    sPts[1].add(T);
    sPts[2].mul(R,wL);
    T.mad(Offset,U,wB);
    sPts[2].add(T);
    sPts[3].mul(R,wR);
    T.mad(Offset,U,wB);
    sPts[3].add(T);

    // find projector direction vectors (from cop through silhouette pts)
    Fvector ProjDirs[4];
    ProjDirs[0].sub(sPts[0],COP);
    ProjDirs[1].sub(sPts[1],COP);
    ProjDirs[2].sub(sPts[2],COP);
    ProjDirs[3].sub(sPts[3],COP);

    //RCache.set_CullMode	(CULL_NONE);
    DRender->CacheSetCullMode(IDebugRender::cmNONE);
    //CHK_DX(HW.pDevice->SetRenderState	(D3DRS_AMBIENT,		0xffffffff			));
    DRender->SetAmbient(0xffffffff);


    Fvector _F[4];
    _F[0].mad(COP, ProjDirs[0], _FAR);
    _F[1].mad(COP, ProjDirs[1], _FAR);
    _F[2].mad(COP, ProjDirs[2], _FAR);
    _F[3].mad(COP, ProjDirs[3], _FAR);

//	u32 CT	= color_rgba(255,255,255,64);
    u32 CL	= color_rgba(0,255,255,255);
    Fmatrix& M	= Fidentity;
    //ref_shader				l_tShaderReference = Level().ObjectSpace.dbgGetShader();
    //RCache.set_Shader		(l_tShaderReference);
    Level().ObjectSpace.m_pRender->SetShader();
//	RCache.dbg_DrawTRI	(M,COP,_F[0],_F[1],CT);
//	RCache.dbg_DrawTRI	(M,COP,_F[1],_F[2],CT);
//	RCache.dbg_DrawTRI	(M,COP,_F[2],_F[3],CT);
//	RCache.dbg_DrawTRI	(M,COP,_F[3],_F[0],CT);
    Level().debug_renderer().draw_line	(M,COP,_F[0],CL);
    Level().debug_renderer().draw_line	(M,COP,_F[1],CL);
    Level().debug_renderer().draw_line	(M,COP,_F[2],CL);
    Level().debug_renderer().draw_line	(M,COP,_F[3],CL);

    Level().debug_renderer().draw_line	(M,_F[0],_F[1],CL);
    Level().debug_renderer().draw_line	(M,_F[1],_F[2],CL);
    Level().debug_renderer().draw_line	(M,_F[2],_F[3],CL);
    Level().debug_renderer().draw_line	(M,_F[3],_F[0],CL);

    //RCache.set_CullMode			(CULL_CCW);
    DRender->CacheSetCullMode(IDebugRender::cmCCW);
    //CHK_DX(HW.pDevice->SetRenderState	(D3DRS_AMBIENT,	0						));
    DRender->SetAmbient(0);
}
Example #13
0
/*
#include "MathUtils.h"
enum EBoxSideNearestPointCode
{
	box_inside		,
	side_invisible	,
	on_side			,
	on_edge			,
	on_vertex
};
EBoxSideNearestPointCode GetNearestPointOnOBBSide(const Fmatrix &xform,const Fvector	&center,const Fvector &sides,u16 side,const Fvector &p,Fvector &point)
{
	//to plane dist
	const Fvector	&norm=xform[side];
	u16 side1=(side+1)%3,side2=(side+2)%3;
	float h=sides[side],h1=sides[side1],h2=sides[side2];
	//Fvector vdiffc;vdiffc.sub(center,p);
	float c_prg=norm.dotproduct(center);
	float p_prg=norm.dotproduct(p);
	float diffc=c_prg-p_prg;norm.dotproduct(vdiffc);
	float diffs;
	if(diffc<0.f)
	{
		diffs=diffc+h;
		point.set(norm);
		point.mul(diffs);
		point.add(p);
		Fvector d;d.sub(center,point);
		bool inside1 =_abs(d[side1])<h1;
		bool inside2 =_abs(d[side2])<h2;
		if(diffs>0.f)
		{
			if(inside1&&inside2) return box_inside;
			else return side_invisible;
		}
		else
		{
			if(inside1&&inside2) return on_side;
			else if(inside1)
			{
				float dd=h2-_abs(d[side2]);
				Fvector s;s.set(xform[side2]);s.
			}
		}
	}
	float diffs=diffc<0.f ? diffc+h	:	diffc-h;
}
*/
IC bool RAYvsCYLINDER(const Fcylinder& c_cylinder, const Fvector &S, const Fvector &D, float &R, BOOL bCull)
{

	const float &r=c_cylinder.m_radius;
	float h=c_cylinder.m_height/2.f;
	const Fvector& p=S;
	const Fvector& dir=D;
	
	const Fvector &c=c_cylinder.m_center;
	const Fvector &ax=c_cylinder.m_direction;
	//c.set(-IM.c.dotproduct(IM.i),-IM.c.dotproduct(IM.j),-IM.c.dotproduct(IM.k));
	//Fvector ax;ax.set(IM.i.z,IM.j.z,IM.k.z);//??

//////////////////////////////////////////////////////////////
	Fvector	v;	v		.sub		(c,p)			;
	float	cs	=dir	.dotproduct	(ax)			;
	float	Lc	=v		.dotproduct	(ax)			;
	float	Lr	=v		.dotproduct	(dir)			;
	////////////////////////////////////////////////
	float sq_cos=cs*cs;
	float sq_sin=1-sq_cos;
	float v_smag=v.square_magnitude();
	const float sq_r=r*r;

	if(sq_sin<EPS)//paralel
	{
		float tr1,tr2								;
		float sq_dist=v_smag-Lr*Lr;//
		if(sq_dist>sq_r) return false;
		float r_dist=_sqrt(sq_r-sq_dist)+h;
		tr1=Lr-r_dist;
		
		if(tr1>R) return false;//
		if(tr1<0.f)
		{
			if(bCull)return false;
			else{
				tr2=Lr+r_dist;
				if(tr2<0.f) return false;//
				if(tr2<R)
				{
					R=tr2;
					return true;
				}
				return false;
			}
		}
		R=tr1;
		return true;
	}

	if(sq_cos<EPS)
	{
		float tr1,tr2								;	
		//perp//
		float abs_c_dist=_abs(Lc);
		if(abs_c_dist>h+r)return false;
		float sq_dist=v_smag-Lr*Lr-Lc*Lc;
		if(sq_dist>sq_r) return false;
		float lc_h=abs_c_dist-h;
		if(lc_h>0.f)
		{
			float sq_sphere_dist=lc_h*lc_h+sq_dist*sq_dist;
			if(sq_sphere_dist>sq_r)return false;
			float diff=_sqrt(sq_r-sq_sphere_dist);
			tr1=Lr-diff;
			if(tr1>R) return false;//
			if(tr1<0.f)
			{
				if(bCull)return false;
				else{
					tr2=Lr+diff;
					if(tr2<0.f) return false;//
					if(tr2<R)
					{
						R=tr2;
						return true;
					}
					return false;
				}
			}
		}
		float diff=_sqrt(sq_r-sq_dist);
		tr1=Lr-diff;
		
		if(tr1>R) return false;//
		if(tr1<0.f)
		{
			if(bCull)return false;
			else{
				tr2=Lr+diff;
				if(tr2<0.f) return false;//
				if(tr2<R)
				{
					R=tr2;
					return true;
				}
				return false;
			}
		}
		R=tr1;
		return true;
	}
//////////////////////////////////////////////////
	float tr1,tr2							;
	float r_sq_sin	=1.f/sq_sin				;
	float tr		=(Lr-cs*Lc)*r_sq_sin	;
	float tc		=(cs*Lr-Lc)*r_sq_sin	;

	//more frequent separation - axes dist> radius
	//v^2+tc^2+tr^2-2*(cos*tc*tr-Lc*tc+Lr*tr)

	float sq_nearest_dist=v_smag+tr*tr+tc*tc-2*(cs*tc*tr-Lc*tc+Lr*tr);

	if(sq_nearest_dist>sq_r) return false;
	//float max_c_diff=//;

	float sq_horde=(sq_r-sq_nearest_dist)		;

	//float horde=_sqrt(sq_horde)					;
	float sq_c_diff=sq_horde*sq_cos*r_sq_sin	;
	float c_diff=_sqrt(sq_c_diff)				;//ccc
	float cp1=tc-c_diff							;
	float cp2=tc+c_diff							;
	
	
	//cp1<cp2 
	if(cp1>h)
	{
		//sphere 
		float tc_h=tc-h;//!! hi					(=)/;
		float sq_sphere_dist=sq_sin*tc_h*tc_h;
		if(sq_sphere_dist>sq_horde)return false;
		float tr_c=tr-tc_h*cs;//
		float diff=_sqrt(sq_horde-sq_sphere_dist);
		tr1=tr_c-diff;
		if(tr1>R) return false;//
		if(tr1<0.f)
		{
			if(bCull)return false;
			else{
				tr2=tr_c+diff;
				if(tr2<0.f) return false;//
				if(tr2<R){R=tr2;return true;}
			}
		}
		R=tr1												;
		return true											;
	} 

	if(cp2<-h)
	{
		//sphere lo								/(=)
		float tc_h=tc+h;//!!
		float sq_sphere_dist=sq_sin*tc_h*tc_h;
		if(sq_sphere_dist>sq_horde)return false;
		float tr_c=tr-tc_h*cs;//!!
		float diff=_sqrt(sq_horde-sq_sphere_dist);
		tr1=tr_c-diff;
		if(tr1>R) return false;//
		if(tr1<0.f)
		{
			if(bCull)return false;
			else{
				tr2=tr_c+diff;
				if(tr2<0.f) return false;//
				if(tr2<R){R=tr2;return true;}
			}
		}
		R=tr1												;
		return true											;
	} 
////////////////////////////////////////////////////////////////
	if(cs>0.f)
	{
		if(cp1 >-h)
		{
			if(cp2<h)
			{
				//cylinder							(=/=)
				float diff=c_diff/cs;
				tr1=tr-diff;
				if(tr1>R) return false;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						tr2=tr+diff;
						if(tr2<0.f) return false;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1												;
				return true											;
			}
			else{
				//mixed//cyl hi sphere					(=/)
				float diff=c_diff/cs					;
				tr1=tr-diff								;
				if(tr1>R) return false;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						float tc_h=tc-h								;
						float sq_sphere_dist=sq_sin*tc_h*tc_h;
						//if(sq_sphere_dist>sq_horde)return false	;
						float tr_c=tr-tc_h*cs						;
						float diff=_sqrt(sq_horde-sq_sphere_dist)	;
						tr2=tr_c+diff								;
						if(tr2<0.f) return false					;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1												;
				return true											;
			}
		}else//cp1<=-h
		{
			if(cp2<h)
			{
				//mixed//lo sphere	cyl						(/=)
				
				float tc_h=tc+h								;//(tc-(-h))
				float sq_sphere_dist=sq_sin*tc_h*tc_h;
				//if(sq_sphere_dist>sq_horde)return false;
				float diff=_sqrt(sq_horde-sq_sphere_dist)	;
				float tr_c=tr-tc_h*cs						;
				tr1=tr_c-diff								;
				if(tr1>R) return false						;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						float diff=c_diff/cs				;
						tr2=tr+diff							;
						if(tr2<0.f) return false			;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1												;
				return true											;
			}else
			{
				//-(--)-								//sphere lo&&hi

				/////////////////////////////////////////////
				float tc_h=tc+h								;
				float tr_c=tr-tc_h*cs						;
				float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h)	;
				tr1=tr_c-diff								;
				if(tr1>R) return false						;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						float tc_h=tc-h								;
						float tr_c=tr-tc_h*cs						;
						float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h)	;
						tr2=tr_c+diff								;
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1												;
				return true											;
			}

		}
	}
	else
	{
		if(cp1 >-h) 
		{
			if(cp2<h)
			{
				//cylinder
				float diff=-c_diff/cs;
				tr1=tr-diff;
				if(tr1>R) return false;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						tr2=tr+diff;
						if(tr2<0.f) return false;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1							;
				return true						;
			}
			else{//cp1>-h&&cp2>h


				float tc_h=tc-h;			//hi sphere/cyl
				float tr_c=tr-tc_h*cs;
				float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h);
				tr1=tr_c-diff;
				if(tr1>R) return false						;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						diff=-c_diff/cs;
						tr2=tr+diff;
						if(tr2<0.f) return false;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1							;
				return true						;
			}
		}else//cp1<-h
		{
			if(cp2<h)
			{
				//cyl/lo sphere
				float diff=-c_diff/cs;
				tr1=tr-diff;
				if(tr1>R) return false						;//
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						//mixed//lo 
						float tc_h=tc+h;			
						float tr_c=tr-tc_h*cs;
						diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h);
						tr2=tr_c+diff;
						if(tr2<0.f) return false;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1							;
				return true						;
			}else//cp2>=h
			{
				//-(--)-								//sphere hi&&lo

				float tc_h=tc-h								;
				float tr_c=tr-tc_h*cs						;
				float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h)	;
				tr1=tr_c-diff								;
				if(tr1>R) return false						;//
				/////////////////////////////////////////////
				if(tr1<0.f)
				{
					if(bCull)return false;
					else{
						tc_h=tc+h								;
						tr_c=tr-tc_h*cs							;
						diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h)	;
						tr2=tr_c+diff							;
						if(tr2<0.f) return false				;//
						if(tr2<R){R=tr2;return true;}
					}
				}
				R=tr1							;
				return true						;
			}
		}
	}
}
Example #14
0
// ----------------------------------------------------------------------
// Name  : classifyPoint()
// Input : point - point we wish to classify
//         pO - Origin of plane
//         pN - Normal to plane
// Notes :
// Return: One of 3 classification codes
// -----------------------------------------------------------------------
IC float classifyPoint(const Fvector& point, const Fvector& planeO, const Fvector& planeN)
{
    Fvector dir;
    dir.sub	(point,planeO);
    return dir.dotproduct(planeN);
}
Example #15
0
BOOL	ValidNode(vertex& N)
{
	// *** Query and cache polygons for ray-casting
	Fvector	PointUp;		PointUp.set(N.Pos);		PointUp.y	+= RCAST_Depth/2;
	Fvector	PointDown;		PointDown.set(N.Pos);	PointDown.y	-= RCAST_Depth/2;

	Fbox	BB;				BB.set	(PointUp,PointUp);		BB.grow(g_params.fPatchSize/2);	// box 1
	Fbox	B2;				B2.set	(PointDown,PointDown);	B2.grow(g_params.fPatchSize/2);	// box 2
	BB.merge(B2			);
	BoxQuery(BB,false	);
	u32	dwCount = XRC.r_count();
	if (dwCount==0)	{
		Log("chasm1");
		return FALSE;			// chasm?
	}

	// *** Transfer triangles and compute sector
	R_ASSERT(dwCount<RCAST_MaxTris);
	static svector<tri,RCAST_MaxTris> tris;		tris.clear();
	for (u32 i=0; i<dwCount; i++)
	{
		tri&		D = tris.last();
		CDB::RESULT&rp = XRC.r_begin()[i];
		*(Level.get_tris()+XRC.r_begin()[i].id);

		D.v[0].set	(rp.verts[0]);
		D.v[1].set	(rp.verts[1]);
		D.v[2].set	(rp.verts[2]);

		Fvector		N;
		N.mknormal	(D.v[0],D.v[1],D.v[2]);
		if (N.y<=0)	continue;

		tris.inc	();
	}
	if (tris.size()==0)	{
		Log("chasm2");
		return FALSE;			// chasm?
	}

	// *** Perform ray-casts and calculate sector
	Fvector P,D,PLP; D.set(0,-1,0);

	float coeff = 0.5f*g_params.fPatchSize/float(RCAST_Count);

	int num_successed_rays = 0;
	for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
	{
		P.x = N.Pos.x + coeff*float(x);
		for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
			P.z = N.Pos.z + coeff*float(z);
			P.y = N.Pos.y;
			N.Plane.intersectRayPoint(P,D,PLP);	// "project" position
			P.y = PLP.y+RCAST_DepthValid/2;

			float	tri_min_range	= flt_max;
			int		tri_selected	= -1;
			float	range = 0.f,u,v;
			for (i=0; i<u32(tris.size()); i++) 
			{
				if (CDB::TestRayTri(P,D,tris[i].v,u,v,range,false)) 
				{
					if (range<tri_min_range) {
						tri_min_range	= range;
						tri_selected	= i;
					}
				}
			}
			if (tri_selected>=0) {
				if (range<RCAST_DepthValid)	num_successed_rays++;

			}
		}
	}
	if (float(num_successed_rays)/float(RCAST_Total) < 0.5f) {
		Msg		("Floating node.");
		return	FALSE;
	}
	return TRUE;
}
Example #16
0
void CMonsterSquad::Attack_AssignTargetDir(ENTITY_VEC &members, const CEntity *enemy)
{
	_elem	first;
	_elem	last;

	lines.clear();

	// сортировать по убыванию расстояния от npc до врага 
	std::sort(members.begin(), members.end(), sort_predicate(enemy));
	if (members.empty()) return;

	float delta_yaw = PI_MUL_2 / members.size();

	// обработать ближний элемент
	first.pE		= members.back();
	first.p_from	= first.pE->Position();
	first.yaw		= 0;
	members.pop_back();

	lines.push_back(first);

	// обработать дальний элемент
	if (!members.empty()) {
		last.pE			= members[0];
		last.p_from		= last.pE->Position();
		last.yaw		= PI;
		members.erase	(members.begin());

		lines.push_back(last);
	}

	Fvector target_pos = enemy->Position();
	float	next_right_yaw	= delta_yaw;
	float	next_left_yaw	= delta_yaw;

	// проходим с конца members в начало (начиная с наименьшего расстояния)
	while (!members.empty()) {
		CEntity *pCur;

		pCur = members.back();
		members.pop_back();

		_elem cur_line;
		cur_line.p_from		= pCur->Position();
		cur_line.pE			= pCur;

		// определить cur_line.yaw

		float h1,p1,h2,p2;
		Fvector dir;
		dir.sub(target_pos, first.p_from);
		dir.getHP(h1,p1);	
		dir.sub(target_pos, cur_line.p_from);
		dir.getHP(h2,p2);

		bool b_add_left = false;

		if (angle_normalize_signed(h2 - h1) > 0)  {		// right
			if ((next_right_yaw < PI) && !fsimilar(next_right_yaw, PI, PI/60.f)) b_add_left = false;
			else b_add_left = true;
		} else {										// left
			if ((next_left_yaw < PI) && !fsimilar(next_left_yaw, PI, PI/60.f)) b_add_left = true;
			else b_add_left = false;
		}

		if (b_add_left) {
			cur_line.yaw = -next_left_yaw;
			next_left_yaw += delta_yaw;
		} else {
			cur_line.yaw = next_right_yaw;
			next_right_yaw += delta_yaw;
		}

		lines.push_back(cur_line);
	}

	// Пройти по всем линиям и заполнить таргеты у npc
	float first_h, first_p;
	Fvector d; d.sub(target_pos,first.p_from);
	d.getHP(first_h, first_p);

	for (u32 i = 0; i < lines.size(); i++){
		SSquadCommand command;
		command.type			= SC_ATTACK;
		command.entity			= enemy;
		command.direction.setHP	(first_h + lines[i].yaw, first_p);
		UpdateCommand(lines[i].pE, command);
	}
}
BOOL ESceneAIMapTools::CreateNode(Fvector& vAt, SAINode& N, bool bIC)
{
	// *** Query and cache polygons for ray-casting
	Fvector	PointUp;		PointUp.set(vAt);	PointUp.y	+= RCAST_Depth;		SnapXZ	(PointUp,m_Params.fPatchSize);
	Fvector	PointDown;		PointDown.set(vAt);	PointDown.y	-= RCAST_Depth;		SnapXZ	(PointDown,m_Params.fPatchSize);

	Fbox	BB;				BB.set	(PointUp,PointUp);		BB.grow(m_Params.fPatchSize/2);	// box 1
	Fbox	B2;				B2.set	(PointDown,PointDown);	B2.grow(m_Params.fPatchSize/2);	// box 2
	BB.merge				(B2);   
    if (m_CFModel)	Scene->BoxQuery(PQ,BB,CDB::OPT_FULL_TEST,m_CFModel);
    else			Scene->BoxQuery(PQ,BB,CDB::OPT_FULL_TEST,GetSnapList());
	DWORD	dwCount 		= PQ.r_count();
	if (dwCount==0){
//		Log("chasm1");
		return FALSE;			// chasm?
	}

	// *** Transfer triangles and compute sector
//	R_ASSERT(dwCount<RCAST_MaxTris);
	static xr_vector<tri> tris;	tris.reserve(RCAST_MaxTris);	tris.clear();
	for (DWORD i=0; i<dwCount; i++)
	{
    	SPickQuery::SResult* R = PQ.r_begin()+i;
        
        if (R->e_obj&&R->e_mesh){
            CSurface* surf		= R->e_mesh->GetSurfaceByFaceID(R->tag);
//.			SGameMtl* mtl 		= GMLib.GetMaterialByID(surf->_GameMtl());
//.			if (mtl->Flags.is(SGameMtl::flPassable))continue;
            Shader_xrLC* c_sh	= Device.ShaderXRLC.Get(surf->_ShaderXRLCName());
            if (!c_sh->flags.bCollision) 			continue;
        }
    
    	tris.push_back	(tri());
		tri&		D = tris.back();
		Fvector*	V = R->verts;   

		D.v[0]		= &V[0];
		D.v[1]		= &V[1];
		D.v[2]		= &V[2];
		D.N.mknormal(*D.v[0],*D.v[1],*D.v[2]);
		if (D.N.y<=0)	tris.pop_back	();
	}
	if (tris.size()==0){
//		Log("chasm2");
		return FALSE;			// chasm?
	}

	static xr_vector<Fvector>	points;		points.reserve(RCAST_Total); points.clear();
	static xr_vector<Fvector>	normals;	normals.reserve(RCAST_Total);normals.clear();
	Fvector P,D; D.set(0,-1,0);

	float coeff 	= 0.5f*m_Params.fPatchSize/float(RCAST_Count);

	for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
	{
		P.x = vAt.x + coeff*float(x); 
		for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
			P.z = vAt.z + coeff*float(z);
			P.y = vAt.y + 10.f;

			float	tri_min_range	= flt_max;
			int		tri_selected	= -1;
			float	range,u,v;
			for (i=0; i<DWORD(tris.size()); i++){
				if (ETOOLS::TestRayTriA(P,D,tris[i].v,u,v,range,false)){
					if (range<tri_min_range){
						tri_min_range	= range;
						tri_selected	= i;
					}
				}
			}
			if (tri_selected>=0) {
				P.y -= tri_min_range;
				points.push_back(P);
				normals.push_back(tris[tri_selected].N);
			}
		}
	}
	if (points.size()<3) {
//		Msg		("Failed to create node at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
		return	FALSE;
	}
//.
	float rc_lim = bIC?0.015f:0.7f;
	if (float(points.size())/float(RCAST_Total) < rc_lim) {
//		Msg		("Partial chasm at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
		return	FALSE;
	}

	// *** Calc normal
	Fvector vNorm;
	vNorm.set(0,0,0);
	for (DWORD n=0; n<normals.size(); n++)
		vNorm.add(normals[n]);
	vNorm.div(float(normals.size()));
	vNorm.normalize();
	/*
	{
		// second algorithm (Magic)
		Fvector N,O;
		N.set(vNorm);
		O.set(points[0]);
		Mgc::OrthogonalPlaneFit(
			points.size(),(Mgc::Vector3*)points.begin(),
			*((Mgc::Vector3*)&O),
			*((Mgc::Vector3*)&N)
		);
		if (N.y<0) N.invert();
		N.normalize();
		vNorm.lerp(vNorm,N,.3f);
		vNorm.normalize();
	}
	*/

 
	// *** Align plane
	Fvector vOffs;
	vOffs.set(0,-1000,0);
	Fplane PL; 	PL.build(vOffs,vNorm);
	for (DWORD p=0; p<points.size(); p++)
	{
		float dist = PL.classify(points[p]);
		if (dist>0) {
			vOffs = points[p];
			PL.build(vOffs,vNorm);
		}
	}

	// *** Create node and register it
	N.Plane.build	(vOffs,vNorm);					// build plane
	D.set			(0,1,0);
	N.Plane.intersectRayPoint(PointDown,D,N.Pos);	// "project" position

	// *** Validate results
	vNorm.set(0,1,0);
	if (vNorm.dotproduct(N.Plane.n)<_cos(deg2rad(60.f)))  return FALSE;

	float y_old = vAt.y;
	float y_new = N.Pos.y;
	if (y_old>y_new) {
		// down
		if (y_old-y_new > m_Params.fCanDOWN ) return FALSE;
	} else {
		// up
		if (y_new-y_old > m_Params.fCanUP	) return FALSE;
	}
 
	// *** Validate plane
	{
		Fvector PLP; D.set(0,-1,0);
		int num_successed_rays = 0;
		for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
		{
			P.x = N.Pos.x + coeff*float(x);
			for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
				P.z = N.Pos.z + coeff*float(z);
				P.y = N.Pos.y;
				N.Plane.intersectRayPoint(P,D,PLP);	// "project" position
				P.y = PLP.y+RCAST_VALID*0.01f;
				
				float	tri_min_range	= flt_max;
				int		tri_selected	= -1;
				float	range,u,v;
				for (i=0; i<tris.size(); i++){
					if (ETOOLS::TestRayTriA(P,D,tris[i].v,u,v,range,false)){
						if (range<tri_min_range){
							tri_min_range	= range;
							tri_selected	= i;
						}
					}
				}
				if (tri_selected>=0){
					if (tri_min_range<RCAST_VALID) num_successed_rays++;
				}
			}
		}
		float perc = float(num_successed_rays)/float(RCAST_Total);
//.		if (!bIC&&(perc < 0.5f)){
		float perc_lim = bIC?0.015f:0.5f;
		if (perc < perc_lim){
			//			Msg		("Floating node.");
			return	FALSE;
		}
	}

	// *** Mask check
	// ???

	return TRUE;
}
Example #18
0
void			CAI_Stalker::Hit					(SHit* pHDS)
{
//	pHDS->power						*= .1f;

	//хит может меняться в зависимости от ранга (новички получают больше хита, чем ветераны)
	SHit							HDS = *pHDS;
	HDS.power						*= m_fRankImmunity;
	if (m_boneHitProtection && HDS.hit_type == ALife::eHitTypeFireWound){
		float						BoneArmour = m_boneHitProtection->getBoneArmour(HDS.bone());	
		float						NewHitPower = HDS.damage() - BoneArmour;
		if (NewHitPower < HDS.power*m_boneHitProtection->m_fHitFrac) HDS.power = HDS.power*m_boneHitProtection->m_fHitFrac;
		else
			HDS.power				= NewHitPower;

		if (wounded())
			HDS.power				= 1000.f;
	}

	if (g_Alive()) {
		bool						already_critically_wounded = critically_wounded();

		if (!already_critically_wounded) {
			const CCoverPoint		*cover = agent_manager().member().member(this).cover();
			if (cover && pHDS->initiator() && (pHDS->initiator()->ID() != ID()) && !fis_zero(pHDS->damage()) && brain().affect_cover())
				agent_manager().location().add	(xr_new<CDangerCoverLocation>(cover,Device.dwTimeGlobal,DANGER_INTERVAL,DANGER_DISTANCE));
		}

		const CEntityAlive	*entity_alive = smart_cast<const CEntityAlive*>(pHDS->initiator());
		if (entity_alive && !wounded()) {
			if (is_relation_enemy(entity_alive))
				sound().play		(eStalkerSoundInjuring);
//			else
//				sound().play		(eStalkerSoundInjuringByFriend);
		}

		int							weapon_type = -1;
		if (best_weapon())
			weapon_type				= best_weapon()->object().ef_weapon_type();

		if	(
				!wounded() &&
				!already_critically_wounded)
		{
			bool					became_critically_wounded = update_critical_wounded(HDS.boneID,HDS.power);
			if	(
				!became_critically_wounded &&
				animation().script_animations().empty() &&
				(pHDS->bone() != BI_NONE)
			)
			{
				Fvector					D;
				float					yaw, pitch;
				D.getHP					(yaw,pitch);

	#pragma todo("Dima to Dima : forward-back bone impulse direction has been determined incorrectly!")
				float					power_factor = m_power_fx_factor*pHDS->damage()/100.f;
				clamp					(power_factor,0.f,1.f);

				CKinematicsAnimated		*tpKinematics = smart_cast<CKinematicsAnimated*>(Visual());
	#ifdef DEBUG
				tpKinematics->LL_GetBoneInstance	(pHDS->bone());
				if (pHDS->bone() >= tpKinematics->LL_BoneCount()) {
					Msg					("tpKinematics has no bone_id %d",pHDS->bone());
					pHDS->_dump			();
				}
	#endif
				int						fx_index = iFloor(tpKinematics->LL_GetBoneInstance(pHDS->bone()).get_param(1) + (angle_difference(movement().m_body.current.yaw,-yaw) <= PI_DIV_2 ? 0 : 1));
				if (fx_index != -1)
					animation().play_fx	(power_factor,fx_index);
			}
			else {
				if (!already_critically_wounded && became_critically_wounded) {
					if (HDS.who) {
						CAI_Stalker		*stalker = smart_cast<CAI_Stalker*>(HDS.who);
						if (stalker)
							stalker->on_critical_wound_initiator	(this);
					}
				}
			}
		}
	}

	inherited::Hit					(&HDS);
}
Example #19
0
void CDeflector::OA_Export()
{
	if (UVpolys.empty()) return;

	// Correct normal
	//  (semi-proportional to pixel density)
	FPU::m64r		();
	Fvector			tN;
	tN.set			(0,0,0);
	float density	= 0;
	float fcount	= 0;
	for (UVIt it = UVpolys.begin(); it!=UVpolys.end(); it++)
	{
		Face	*F = it->owner;
		Fvector	SN;
		SN.set	(F->N);
		SN.mul	(1+EPS*F->CalcArea());
		tN.add	(SN);

		density	+= F->Shader().lm_density;
		fcount	+= 1.f;
	}
	if (tN.magnitude()>EPS_S && _valid(tN))	normal.set(tN).normalize();
	else									clMsg("* ERROR: Internal precision error in CDeflector::OA_Export");
	density			/= fcount;
	
	// Orbitrary Oriented Ortho - Projection
	Fmatrix		mView;
    Fvector		at,from,up,right,y;
	at.set		(0,0,0);
	from.add	(at,normal);
	y.set		(0,1,0);
	if (_abs(normal.y)>.99f)		y.set(1,0,0);
	right.crossproduct(y,normal);	right.normalize_safe();
	up.crossproduct(normal,right);	up.normalize_safe();
	mView.build_camera(from,at,up);

	Fbox bb; bb.invalidate();
	for (UVIt it = UVpolys.begin(); it!=UVpolys.end(); it++)
	{
		UVtri	*T = &*it;
		Face	*F = T->owner;
		Fvector	P;	// projected

		for (int i=0; i<3; i++) {
			mView.transform_tiny	(P,F->v[i]->P);
			T->uv[i].set			(P.x,P.y);
			bb.modify				(F->v[i]->P);
		}
	}
	bb.getsphere(Sphere.P,Sphere.R);

	// UV rect
	Fvector2		min,max,size;
	GetRect			(min,max);
	size.sub		(max,min);

	// Surface
	u32 dwWidth		= iCeil(size.x*g_params.m_lm_pixels_per_meter*density+.5f); clamp(dwWidth, 1u,512u-2*BORDER);
	u32 dwHeight	= iCeil(size.y*g_params.m_lm_pixels_per_meter*density+.5f); clamp(dwHeight,1u,512u-2*BORDER);
	layer.create	(dwWidth,dwHeight);
}
Example #20
0
void CAI_Stalker::throw_target				(const Fvector &position)
{
	float					distance_to_sqr = position.distance_to_sqr(m_throw_target);
	m_throw_actual			= m_throw_actual && (distance_to_sqr < _sqr(.1f));
	m_throw_target			= position;
}
Example #21
0
void CBuild::BuildRelevance(IWriter &fs)
{
	static Fvector size;
	static u32	nx,ny,nz;

	Status("Preparing...");
	R_ASSERT(g_TREE_ROOT);
	g_TREE_ROOT->bbox.getsize(size);
	clMsg("Level dimensions: [%3.1f,%3.1f,%3.1f]",size.x,size.y,size.z);
	nx = iROUND(ceilf(size.x/g_params.m_relevance));
	ny = iROUND(ceilf(size.y/g_params.m_relevance));
	nz = iROUND(ceilf(size.z/g_params.m_relevance));
	clMsg("Ceiling dimensions: [%3d,%3d,%3d]",nx, ny, nz);

	fs.open_chunk(fsL_VISIBILITY);
 
	fs.open_chunk(fsV_HEADER);
	V_Header		H;
	H.nX			= nx;
	H.nY			= ny;
	H.nZ			= nz;
	H.relevance		= g_params.m_relevance;
	H.min.set		(g_TREE_ROOT->bbox.min);
	fs.write		(&H,sizeof(H));
	fs.close_chunk	();

	// Build Visibility
	static xr_vector< u32 >		slots;
	static xr_vector< vecW >		vis_nodes;
	static xr_vector< vecW >		vis_lights;
	static xr_vector< vecW >		vis_glows;
	static xr_vector< vecW >		vis_occluders;
	static vecW					rel_set;
	static vecW					unroll;

	CVirtualFileStream*			pvs_map_stream=0;
	if (g_params.m_bTestOcclusion)
	{
		pvs_map_stream  = xr_new<CVirtualFileStream> ("pvs.temp");
		g_pvs_map_vm	= (int *)pvs_map_stream->Pointer();
	}
 
	static u32				dwSlot = 0;
	for (int z=0; z<nz; z++) {
		for (int x=0; x<nx; x++) {
			for (int y=0; y<ny; y++)
			{
				Status("Volume #%d...",dwSlot);
				static Fvector pos;
				pos.set(x,y,z);
				pos.add(.5f);
				pos.mul(g_params.m_relevance);
				pos.add(g_TREE_ROOT->bbox.min);

				// ******* Nodes relevance
				if (g_params.m_bTestOcclusion)
				{
					CalculateRelSet(pos,unroll);
					if (unroll.empty() || g_TREE_ROOT->VisCapture(unroll,rel_set))
						rel_set.push_back(g_tree.size()-1);
					unroll.clear();
					slots.push_back(PlaceData(vis_nodes,rel_set));
				} else {
					// Unroll hierrarhy
					VERIFY(g_TREE_ROOT);
					g_TREE_ROOT->VisUnroll(pos,unroll);
					if (unroll.size()>1)
						std::sort(unroll.begin(),unroll.end());
					// Capture results
					if (g_TREE_ROOT->VisCapture(unroll,rel_set))
						rel_set.push_back(g_tree.size()-1);
					unroll.clear();
					// Register in container
					slots.push_back(PlaceData(vis_nodes,rel_set));
				}

				// Lights relevance
				for (int i=0; i<lights.size(); i++)
				{
					if ((pos.distance_to(lights[i].position) - lights[i].range) < g_params.m_viewdist) {
						rel_set.push_back(i);
					}
				}
				slots.push_back(PlaceData(vis_lights,rel_set));

				// Glows relevance
				for (i=0; i<glows.size(); i++)
				{
					if ((pos.distance_to(glows[i].P) - glows[i].size) < g_params.m_viewdist) {
						rel_set.push_back(i);
					}
				}
				slots.push_back(PlaceData(vis_glows,rel_set));

				// Occluders relevance
				for (i=0; i<occluders.size(); i++)
				{
					Fvector P; float R=-1; float T;
					P.add(occluders[i].V2,occluders[i].V4);
					P.mul(.5f);
					T = P.distance_to(occluders[i].V1); if (T>R) R=T;
					T = P.distance_to(occluders[i].V2); if (T>R) R=T;
					T = P.distance_to(occluders[i].V4); if (T>R) R=T;
					if ((pos.distance_to(P) - R) < g_params.m_viewdist*g_params.m_occluder_rel_scale) {
						rel_set.push_back(i);
					}
				}
				slots.push_back(PlaceData(vis_occluders,rel_set));

				dwSlot++;
				Progress(float(dwSlot)/float(nz*nx*ny));
			}
		}
	}


	xr_delete		(pvs_map_stream);

	fs.open_chunk	(fsV_NODES);
	SaveDATA		(fs,vis_nodes);
	fs.close_chunk	();

	fs.open_chunk(fsV_LIGHTS);
	SaveDATA(fs,vis_lights);
	fs.close_chunk();

	fs.open_chunk(fsV_GLOWS);
	SaveDATA(fs,vis_glows);
	fs.close_chunk();

	fs.open_chunk(fsV_OCCLUDERS);
	SaveDATA(fs,vis_occluders);
	fs.close_chunk();

	fs.open_chunk(fsV_MAP);
	fs.write(slots.begin(),slots.size()*sizeof(u32));
	fs.close_chunk();

	fs.close_chunk();
}
Example #22
0
void CAI_Stalker::g_fireParams(const CHudItem* pHudItem, Fvector& P, Fvector& D)
{
//.	VERIFY				(inventory().ActiveItem());
	if (!inventory().ActiveItem()) {
#ifdef DEBUG
		Msg				("! CAI_Stalker::g_fireParams() : VERIFY(inventory().ActiveItem())");
#endif // DEBUG
		P				= Position();
		D				= Fvector().set(0.f,0.f,1.f);
		return;
	}

	CWeapon				*weapon = smart_cast<CWeapon*>(inventory().ActiveItem());
	if (!weapon) {
		CMissile		*missile = smart_cast<CMissile*>(inventory().ActiveItem());
		if (missile) {
			update_throw_params	();
			P			= m_throw_position;
			D			= m_throw_direction;
			VERIFY		(!fis_zero(D.square_magnitude()));
			return;
		}
		P				= eye_matrix.c;
		D				= eye_matrix.k;
		if (weapon_shot_effector().IsActive())
			D			= weapon_shot_effector_direction(D);
		VERIFY			(!fis_zero(D.square_magnitude()));
		return;
	}

	if (!g_Alive()) {
		P				= weapon->get_LastFP();
		D				= weapon->get_LastFD();
		VERIFY			(!fis_zero(D.square_magnitude()));
		return;
	}

	switch (movement().body_state()) {
		case eBodyStateStand : {
			if (movement().movement_type() == eMovementTypeStand) {
				P		= eye_matrix.c;
				D		= eye_matrix.k;
				if (weapon_shot_effector().IsActive())
					D	= weapon_shot_effector_direction(D);
				VERIFY	(!fis_zero(D.square_magnitude()));
			}
			else {
				D.setHP	(-movement().m_head.current.yaw,-movement().m_head.current.pitch);
				if (weapon_shot_effector().IsActive())
					D			= weapon_shot_effector_direction(D);
				Center	(P);
				P.mad	(D,.5f);
				P.y		+= .50f;
//				P		= weapon->get_LastFP();
//				D		= weapon->get_LastFD();
				VERIFY	(!fis_zero(D.square_magnitude()));
			}
			return;
		}
		case eBodyStateCrouch : {
			P			= eye_matrix.c;
			D			= eye_matrix.k;
			if (weapon_shot_effector().IsActive())
				D		= weapon_shot_effector_direction(D);
			VERIFY		(!fis_zero(D.square_magnitude()));
			return;
		}
		default			: NODEFAULT;
	}

#ifdef DEBUG
	P					= weapon->get_LastFP();
	D					= weapon->get_LastFD();
	VERIFY				(!fis_zero(D.square_magnitude()));
#endif
}
Example #23
0
BOOL	CreateNode(Fvector& vAt, vertex& N)
{
	// *** Query and cache polygons for ray-casting
	Fvector	PointUp;		PointUp.set(vAt);	PointUp.y	+= RCAST_Depth;		SnapXZ	(PointUp);
	Fvector	PointDown;		PointDown.set(vAt);	PointDown.y	-= RCAST_Depth;		SnapXZ	(PointDown);

	Fbox	BB;				BB.set	(PointUp,PointUp);		BB.grow(g_params.fPatchSize/2);	// box 1
	Fbox	B2;				B2.set	(PointDown,PointDown);	B2.grow(g_params.fPatchSize/2);	// box 2
	BB.merge(B2			);
	BoxQuery(BB,false	);
	u32	dwCount = XRC.r_count();
	if (dwCount==0)	{
//		Log("chasm1");
		return FALSE;			// chasm?
	}

	// *** Transfer triangles and compute sector
	R_ASSERT(dwCount<RCAST_MaxTris);
	static svector<tri,RCAST_MaxTris> tris;		tris.clear();
	for (u32 i=0; i<dwCount; i++)
	{
		tri&		D = tris.last();
		CDB::RESULT	&rp = XRC.r_begin()[i];
		CDB::TRI&	T = *(Level.get_tris()+rp.id);

		D.v[0].set	(rp.verts[0]);
		D.v[1].set	(rp.verts[1]);
		D.v[2].set	(rp.verts[2]);
		D.sector	= T.sector;
		D.N.mknormal(D.v[0],D.v[1],D.v[2]);
		if (D.N.y<=0)	continue;

		tris.inc	();
	}
	if (tris.size()==0)	{
//		Log("chasm2");
		return FALSE;			// chasm?
	}

	// *** Perform ray-casts and calculate sector
	WORD Sector = 0xfffe;	// mark as first time

	static svector<Fvector,RCAST_Total>	points;		points.clear();
	static svector<Fvector,RCAST_Total>	normals;	normals.clear();
	Fvector P,D; D.set(0,-1,0);

	float coeff = 0.5f*g_params.fPatchSize/float(RCAST_Count);

	for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
	{
		P.x = vAt.x + coeff*float(x);
		for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
			P.z = vAt.z + coeff*float(z);
			P.y = vAt.y + 10.f;

			float	tri_min_range	= flt_max;
			int		tri_selected	= -1;
			float	range,u,v;
			for (i=0; i<u32(tris.size()); i++) 
			{
				if (CDB::TestRayTri(P,D,tris[i].v,u,v,range,false)) 
				{
					if (range<tri_min_range) {
						tri_min_range	= range;
						tri_selected	= i;
					}
				}
			}
			if (tri_selected>=0) {
				P.y -= tri_min_range;
				points.push_back(P);
				normals.push_back(tris[tri_selected].N);
				WORD TS = WORD(tris[tri_selected].sector);
				if (Sector==0xfffe)	Sector = TS;
				else 				if (Sector!=TS) Sector=InvalidSector;
			}
		}
	}
	if (points.size()<3) {
//		Msg		("Failed to create node at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
		return	FALSE;
	}
	if (float(points.size())/float(RCAST_Total) < 0.7f) {
//		Msg		("Partial chasm at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
		return	FALSE;
	}

	// *** Calc normal
	Fvector vNorm;
	vNorm.set(0,0,0);
	for (u32 n=0; n<normals.size(); n++)
		vNorm.add(normals[n]);
	vNorm.div(float(normals.size()));
	vNorm.normalize();
	/*
	{
		// second algorithm (Magic)
		Fvector N,O;
		N.set(vNorm);
		O.set(points[0]);
		Mgc::OrthogonalPlaneFit(
			points.size(),(Mgc::Vector3*)points.begin(),
			*((Mgc::Vector3*)&O),
			*((Mgc::Vector3*)&N)
		);
		if (N.y<0) N.invert();
		N.normalize();
		vNorm.lerp(vNorm,N,.3f);
		vNorm.normalize();
	}
	*/

 
	// *** Align plane
	Fvector vOffs;
	vOffs.set(0,-1000,0);
	Fplane PL; 	PL.build(vOffs,vNorm);
	for (u32 p=0; p<points.size(); p++)
	{
		float dist = PL.classify(points[p]);
		if (dist>0) {
			vOffs = points[p];
			PL.build(vOffs,vNorm);
		}
	}

	// *** Create node and register it
	N.Sector		=Sector;						// sector
	N.Plane.build	(vOffs,vNorm);					// build plane
	D.set			(0,1,0);
	N.Plane.intersectRayPoint(PointDown,D,N.Pos);	// "project" position

	// *** Validate results
	vNorm.set(0,1,0);
	if (vNorm.dotproduct(N.Plane.n)<_cos(deg2rad(60.f)))  return FALSE;

	float y_old = vAt.y;
	float y_new = N.Pos.y;
	if (y_old>y_new) {
		// down
		if (y_old-y_new > g_params.fCanDOWN ) return FALSE;
	} else {
		// up
		if (y_new-y_old > g_params.fCanUP	) return FALSE;
	}
 
	// *** Validate plane
	{
		Fvector PLP; D.set(0,-1,0);
		int num_successed_rays = 0;
		for (int x=-RCAST_Count; x<=RCAST_Count; x++) 
		{
			P.x = N.Pos.x + coeff*float(x);
			for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
				P.z = N.Pos.z + coeff*float(z);
				P.y = N.Pos.y;
				N.Plane.intersectRayPoint(P,D,PLP);	// "project" position
				P.y = PLP.y+RCAST_VALID*0.01f;
				
				float	tri_min_range	= flt_max;
				int		tri_selected	= -1;
				float	range,u,v;
				for (i=0; i<float(tris.size()); i++) 
				{
					if (CDB::TestRayTri(P,D,tris[i].v,u,v,range,false)) 
					{
						if (range<tri_min_range) {
							tri_min_range	= range;
							tri_selected	= i;
						}
					}
				}
				if (tri_selected>=0) {
					if (tri_min_range<RCAST_VALID) num_successed_rays++;
				}
			}
		}
		float perc = float(num_successed_rays)/float(RCAST_Total);
		if (perc < 0.5f) {
			//			Msg		("Floating node.");
			return	FALSE;
		}
	}

	// *** Mask check
	// ???

	return TRUE;
}
Example #24
0
void CMincer ::ThrowInCenter(Fvector& C)
{
	C.set(m_telekinetics.Center());
	C.y=Position().y;
}
Example #25
0
void CPEDef::ExecuteCollision(PAPI::Particle* particles, u32 p_cnt, float dt, CParticleEffect* owner, CollisionCallback cb)
{
	pVector pt,n;
	// Must traverse list in reverse order so Remove will work
	for(int i = p_cnt-1; i >= 0; i--){
		Particle &m = particles[i];

		bool pick_needed;
		int pick_cnt=0;
		do{		
			pick_needed = false;
			Fvector 	dir;
			dir.sub		(m.pos,m.posB);
			float dist 	= dir.magnitude();
			if (dist>=EPS){
				dir.div	(dist);
#ifdef _EDITOR                
				if (Tools->RayPick(m.posB,dir,dist,&pt,&n)){
#else
				collide::rq_result	RQ;
                collide::rq_target	RT = m_Flags.is(dfCollisionDyn)?collide::rqtBoth:collide::rqtStatic;
				if (g_pGameLevel->ObjectSpace.RayPick(m.posB,dir,dist,RT,RQ,NULL)){	
					pt.mad	(m.posB,dir,RQ.range);
					if (RQ.O){
						n.set(0.f,1.f,0.f);
					}else{
						CDB::TRI*	T		=  	g_pGameLevel->ObjectSpace.GetStaticTris()+RQ.element;
						Fvector*	verts	=	g_pGameLevel->ObjectSpace.GetStaticVerts();
						n.mknormal(verts[T->verts[0]],verts[T->verts[1]],verts[T->verts[2]]);
					}
#endif
					pick_cnt++;
					if (cb&&(pick_cnt==1)) if (!cb(owner,m,pt,n)) break;
					if (m_Flags.is(dfCollisionDel)){ 
	                   	ParticleManager()->RemoveParticle(owner->m_HandleEffect,i);
					}else{
						// Compute tangential and normal components of velocity
						float nmag = m.vel * n;
						pVector vn(n * nmag); 	// Normal Vn = (V.N)N
						pVector vt(m.vel - vn);	// Tangent Vt = V - Vn

						// Compute _new velocity heading out:
						// Don't apply friction if tangential velocity < cutoff
						if(vt.length2() <= m_fCollideSqrCutoff){
							m.vel = vt - vn * m_fCollideResilience;
						}else{
							m.vel = vt * m_fCollideOneMinusFriction - vn * m_fCollideResilience;
						}
						m.pos	= m.posB + m.vel * dt; 
						pick_needed = true;
					}
				}
			}else{
				m.pos	= m.posB;
			}
		}while(pick_needed&&(pick_cnt<2));
	}
}

//------------------------------------------------------------------------------
// I/O part
//------------------------------------------------------------------------------
BOOL CPEDef::Load(IReader& F)
{
	R_ASSERT		(F.find_chunk(PED_CHUNK_VERSION));
	u16 version		= F.r_u16();

	if (version!=PED_VERSION)
		return FALSE;

	R_ASSERT		(F.find_chunk(PED_CHUNK_NAME));
	F.r_stringZ		(m_Name);

	R_ASSERT		(F.find_chunk(PED_CHUNK_EFFECTDATA));
	m_MaxParticles	= F.r_u32();

	u32 sz			= F.find_chunk(PED_CHUNK_ACTIONLIST); R_ASSERT(sz);
	m_Actions.w		(F.pointer(),sz);

	F.r_chunk		(PED_CHUNK_FLAGS,&m_Flags);

	if (m_Flags.is(dfSprite)){
		R_ASSERT	(F.find_chunk(PED_CHUNK_SPRITE));
		F.r_stringZ	(m_ShaderName);
		F.r_stringZ	(m_TextureName);
	}

	if (m_Flags.is(dfFramed)){
		R_ASSERT	(F.find_chunk(PED_CHUNK_FRAME));
		F.r			(&m_Frame,sizeof(SFrame));
	}

	if (m_Flags.is(dfTimeLimit)){
		R_ASSERT(F.find_chunk(PED_CHUNK_TIMELIMIT));
		m_fTimeLimit= F.r_float();
	}

	if (m_Flags.is(dfCollision)){
		R_ASSERT(F.find_chunk(PED_CHUNK_COLLISION));
		m_fCollideOneMinusFriction 	= F.r_float();
		m_fCollideResilience		= F.r_float();
		m_fCollideSqrCutoff			= F.r_float();
	}

	if (m_Flags.is(dfVelocityScale)){
		R_ASSERT(F.find_chunk(PED_CHUNK_VEL_SCALE));
		F.r_fvector3				(m_VelocityScale); 
	}

	if (m_Flags.is(dfAlignToPath)){
		if (F.find_chunk(PED_CHUNK_ALIGN_TO_PATH)){
			F.r_fvector3			(m_APDefaultRotation);
		}
	}

#ifdef _EDITOR
	if (F.find_chunk(PED_CHUNK_OWNER)){
		AnsiString tmp;
		F.r_stringZ	(m_OwnerName);
		F.r_stringZ	(m_ModifName);
		F.r			(&m_CreateTime,sizeof(m_CreateTime));
		F.r			(&m_ModifTime,sizeof(m_ModifTime));
	}
    if (pCreateEAction&&F.find_chunk(PED_CHUNK_EDATA)){
        m_EActionList.resize(F.r_u32());
        for (EPAVecIt it=m_EActionList.begin(); it!=m_EActionList.end(); it++){
            PAPI::PActionEnum type = (PAPI::PActionEnum)F.r_u32();
            (*it)	= pCreateEAction(type);
            (*it)->Load		(F);
        }
    } 
#endif

	return TRUE;
}
Example #26
0
void CMincer ::Center	(Fvector& C) const
{
	C.set(Position());
}
bool CPolterTele::tele_raise_objects()
{
	// find objects near actor
	xr_vector<CObject*>		tele_objects;
	tele_objects.reserve	(20);

	// получить список объектов вокруг врага
	tele_find_objects	(tele_objects, Actor()->Position());

	// получить список объектов вокруг монстра
	tele_find_objects	(tele_objects, m_object->Position());

	// получить список объектов между монстром и врагом
	float dist			= Actor()->Position().distance_to(m_object->Position());
	Fvector dir;
	dir.sub				(Actor()->Position(), m_object->Position());
	dir.normalize		();

	Fvector pos;
	pos.mad				(m_object->Position(), dir, dist / 2.f);
	tele_find_objects	(tele_objects, pos);	

	// сортировать и оставить только необходимое количество объектов
	std::sort(tele_objects.begin(),tele_objects.end(),best_object_predicate2(m_object->Position(), Actor()->Position()));
	
	// оставить уникальные объекты
	tele_objects.erase	(
		std::unique(
			tele_objects.begin(),
			tele_objects.end()
		),
		tele_objects.end()
	);

	// оставить необходимое количество объектов
	//if (tele_objects.size() > m_pmt_tele_object_count) tele_objects.resize	(m_pmt_tele_object_count);

	//// активировать
	//for (u32 i=0; i<tele_objects.size(); i++) {
	//	CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(tele_objects[i]);

	//	// применить телекинез на объект
	//	bool	rotate = false;

	//	CTelekinesis::activate		(obj, m_pmt_tele_raise_speed, m_pmt_tele_object_height, m_pmt_tele_time_object_keep, rotate);
	//}

	if (!tele_objects.empty()) {
		CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(tele_objects[0]);

		// применить телекинез на объект
		bool	rotate = false;

		CTelekineticObject		*tele_obj = m_object->CTelekinesis::activate		(obj, m_pmt_raise_speed, m_pmt_object_height, m_pmt_time_object_keep, rotate);
		tele_obj->set_sound		(m_sound_tele_hold,m_sound_tele_throw);

		return true;
	}

	return false;
}
Example #28
0
void CPHDestroyable::NotificatePart(CPHDestroyableNotificate *dn)
{
	CPhysicsShell	*own_shell=PPhysicsShellHolder()->PPhysicsShell()			;
	CPhysicsShell	*new_shell=dn->PPhysicsShellHolder()->PPhysicsShell()		;
	IKinematics		*own_K =smart_cast<IKinematics*>(PPhysicsShellHolder()->Visual());
	IKinematics		*new_K =smart_cast<IKinematics*>(dn->PPhysicsShellHolder()->Visual())	;
	VERIFY			(own_K&&new_K&&own_shell&&new_shell)						;
	CInifile		*own_ini  =own_K->LL_UserData()								;
	CInifile		*new_ini  =new_K->LL_UserData()								;
	//////////////////////////////////////////////////////////////////////////////////	
	Fmatrix			own_transform;
	own_shell		->GetGlobalTransformDynamic		(&own_transform)			;
	new_shell		->SetGlTransformDynamic			(own_transform)				;
	////////////////////////////////////////////////////////////

	////////////////////////////////////////////////////////////////////////////////////
	float						random_min										=1.f	;  
	float						random_hit_imp									=1.f	;
	////////////////////////////////////////////////////////////////////////////////////
	u16							ref_bone										=own_K->LL_GetBoneRoot();

	float						imp_transition_factor							=1.f	;
	float						lv_transition_factor							=1.f	;
	float						av_transition_factor							=1.f	;
	////////////////////////////////////////////////////////////////////////////////////
	if(own_ini&&own_ini->section_exist("impulse_transition_to_parts"))
	{
		random_min				=own_ini->r_float("impulse_transition_to_parts","random_min");
		random_hit_imp			=own_ini->r_float("impulse_transition_to_parts","random_hit_imp");
		////////////////////////////////////////////////////////
		if(own_ini->line_exist("impulse_transition_to_parts","ref_bone"))
			ref_bone				=own_K->LL_BoneID(own_ini->r_string("impulse_transition_to_parts","ref_bone"));
		imp_transition_factor	=own_ini->r_float("impulse_transition_to_parts","imp_transition_factor");
		lv_transition_factor	=own_ini->r_float("impulse_transition_to_parts","lv_transition_factor");
		av_transition_factor	=own_ini->r_float("impulse_transition_to_parts","av_transition_factor");

		if(own_ini->section_exist("collide_parts"))
		{
			if(own_ini->line_exist("collide_parts","small_object"))
			{
				new_shell->SetSmall();
			}
			if(own_ini->line_exist("collide_parts","ignore_small_objects"))
			{
				new_shell->SetIgnoreSmall();
			}
		}
	}

	if(new_ini&&new_ini->section_exist("impulse_transition_from_source_bone"))
	{
		//random_min				=new_ini->r_float("impulse_transition_from_source_bone","random_min");
		//random_hit_imp			=new_ini->r_float("impulse_transition_from_source_bone","random_hit_imp");
		////////////////////////////////////////////////////////
		if(new_ini->line_exist("impulse_transition_from_source_bone","ref_bone"))
			ref_bone				=own_K->LL_BoneID(new_ini->r_string("impulse_transition_from_source_bone","ref_bone"));
		imp_transition_factor	=new_ini->r_float("impulse_transition_from_source_bone","imp_transition_factor");
		lv_transition_factor	=new_ini->r_float("impulse_transition_from_source_bone","lv_transition_factor");
		av_transition_factor	=new_ini->r_float("impulse_transition_from_source_bone","av_transition_factor");
	}
	//////////////////////////////////////////////////////////////////////////////////////////////////////


		dBodyID own_body=own_shell->get_Element(ref_bone)->get_body()			;

		u16 new_el_number = new_shell->get_ElementsNumber()									;

		for(u16 i=0;i<new_el_number;++i)
		{
			CPhysicsElement* e=new_shell->get_ElementByStoreOrder(i);
			float random_hit=random_min*e->getMass();
			if(m_fatal_hit.is_valide() && m_fatal_hit.bone()!=BI_NONE )
			{
				Fvector pos;
				Fmatrix m;m.set(own_K->LL_GetTransform(m_fatal_hit.bone()));
				m.mulA_43		(PPhysicsShellHolder()->XFORM());
				m.transform_tiny(pos,m_fatal_hit.bone_space_position());
				e->applyImpulseVsGF(pos,m_fatal_hit.direction(),m_fatal_hit.phys_impulse()*imp_transition_factor);
				random_hit+=random_hit_imp*m_fatal_hit.phys_impulse();
			}
			Fvector rnd_dir;rnd_dir.random_dir();
			e->applyImpulse(rnd_dir,random_hit);
			Fvector mc; mc.set(e->mass_Center());
			dVector3 res_lvell;
			dBodyGetPointVel(own_body,mc.x,mc.y,mc.z,res_lvell);
			cast_fv(res_lvell).mul(lv_transition_factor);
			e->set_LinearVel(cast_fv(res_lvell));
			
			Fvector res_avell;res_avell.set(cast_fv(dBodyGetAngularVel(own_body)));
			res_avell.mul(av_transition_factor);
			e->set_AngularVel(res_avell);
		}
	




	new_shell->Enable();
	new_shell->EnableCollision();
	dn->PPhysicsShellHolder()->setVisible(TRUE);
	dn->PPhysicsShellHolder()->setEnabled(TRUE);

	if(own_shell->IsGroupObject())
		new_shell->RegisterToCLGroup(own_shell->GetCLGroup());//CollideBits
	CPHSkeleton* ps=dn->PPhysicsShellHolder()->PHSkeleton();
	if(ps)
	{
	
		if(own_ini&&own_ini->section_exist("autoremove_parts"))
		{
			ps->SetAutoRemove(1000*(READ_IF_EXISTS(own_ini,r_u32,"autoremove_parts","time",ps->DefaultExitenceTime())));
		}

		if(new_ini&&new_ini->section_exist("autoremove"))
		{
			ps->SetAutoRemove(1000*(READ_IF_EXISTS(new_ini,r_u32,"autoremove","time",ps->DefaultExitenceTime())));
		}
	}

}
Example #29
0
void CLightShadows::calculate	()
{
	if (casters.empty())		return;

	BOOL bRTS					= FALSE;
	Device.Statistic->RenderDUMP_Scalc.Begin	();
	HW.pDevice->SetRenderState	(D3DRS_ZENABLE, D3DZB_FALSE);
	
	// iterate on objects
	int	slot_id		= 0;
	int slot_line	= S_rt_size/S_size;
	int slot_max	= slot_line*slot_line;
	const float	eps = 2*EPS_L;
	for (u32 o_it=0; o_it<casters.size(); o_it++)
	{
		caster&	C	= *casters	[o_it];
		if (C.nodes.empty())	continue;
		
		// Select lights and calc importance
		CROS_impl* LT			= (CROS_impl*)C.O->renderable_ROS();
		xr_vector<CROS_impl::Light>& lights = LT->lights;
		
		// iterate on lights
		for (u32 l_it=0; (l_it<lights.size()) && (slot_id<slot_max); l_it++)
		{
			CROS_impl::Light&	L			=	lights[l_it];
			if (L.energy<S_level)			continue;
			
			//Msg	("~ light: %d",l_it);

			// setup rt+state(s) for first use
			if (!bRTS)	{
				bRTS						= TRUE;
				RCache.set_RT				(RT_temp->pRT);
				RCache.set_ZB				(RImplementation.Target->pTempZB);
				HW.pDevice->Clear			(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,255,255),1,0);
			}

			// calculate light center
			Fvector		Lpos	= L.source->position;
			float		Lrange	= L.source->range;
			//Log	("* l-pos:",Lpos);
			//Msg	("* l-range: %f",Lrange);
			if (L.source->flags.type==IRender_Light::DIRECT)
			{
				// Msg		(" -direct- : %f",L.energy);
				Lpos.mul	(L.source->direction,-100);
				Lpos.add	(C.C);
				Lrange		= 120;
			} else {
				VERIFY		(_valid(Lpos));
				VERIFY		(_valid(C.C));
				float		_dist	;
				while		(true)	{
					_dist	=	C.C.distance_to	(Lpos);
					//Msg		("* o-dist: %f",	_dist);
					if (_dist>EPS_L)		break;
					Lpos.y					+=	.01f;	//. hack to avoid light-in-the-center-of-object
				}
				float		_R		=	C.O->renderable.visual->vis.sphere.R+0.1f;
				//Msg	("* o-r: %f",_R);
				if (_dist<_R)		{
					Fvector			Ldir;
					Ldir.sub		(C.C,Lpos);
					Ldir.normalize	();
					Lpos.mad		(Lpos,Ldir,_dist-_R);
					//Msg	("* moving lpos");
				}
			}
			
			// calculate projection-matrix
			Fmatrix		mProject,mProjectR;
			float		p_dist	=	C.C.distance_to(Lpos);
			float		p_R		=	C.O->renderable.visual->vis.sphere.R;
			float		p_hat	=	p_R/p_dist;
			float		p_asp	=	1.f;
			float		p_near	=	p_dist-p_R-eps;									
			float		p_nearR	=	C.C.distance_to(L.source->position) + p_R*0.85f + eps;
						p_nearR =	p_near;
			float		p_far	=	_min(Lrange,_max(p_dist+S_fade,p_dist+p_R));	
			if (p_near<eps)			continue;
			if (p_far<(p_near+eps))	continue;
			if (p_hat>0.9f)			continue;
			if (p_hat<0.01f)		continue;

			//Msg			("* near(%f), near-x(%f)",p_near,p_nearR);
			
			mProject.build_projection_HAT	(p_hat,p_asp,p_near,	p_far);
			mProjectR.build_projection_HAT	(p_hat,p_asp,p_nearR,	p_far);
			RCache.set_xform_project		(mProject);
			
			// calculate view-matrix
			Fmatrix		mView;
			Fvector		v_D,v_N,v_R;
			v_D.sub					(C.C,Lpos);
			v_D.normalize			();
			if(1-_abs(v_D.y)<EPS)	v_N.set(1,0,0);
			else            		v_N.set(0,1,0);
			v_R.crossproduct		(v_N,v_D);
			v_N.crossproduct		(v_D,v_R);
			mView.build_camera		(Lpos,C.C,v_N);
			RCache.set_xform_view	(mView);
			
			// combine and build frustum
			Fmatrix					mCombine,mCombineR;
			mCombine.mul			(mProject,mView);
			mCombineR.mul			(mProjectR,mView);
			
			// Select slot and set viewport
			int		s_x			=	slot_id%slot_line;
			int		s_y			=	slot_id/slot_line;
			D3DVIEWPORT9 VP		=	{s_x*S_size,s_y*S_size,S_size,S_size,0,1 };
			CHK_DX					(HW.pDevice->SetViewport(&VP));
			
			// Render object-parts
			for (u32 n_it=0; n_it<C.nodes.size(); n_it++)
			{
				NODE& N					=	C.nodes[n_it];
				IRender_Visual *V		=	N.pVisual;
				RCache.set_Element		(V->shader_ref->E[SE_R1_LMODELS]);
				RCache.set_xform_world	(N.Matrix);
				V->Render				(-1.0f);
			}
			
			// register shadow and increment slot
			shadows.push_back		(shadow());
			shadows.back().O		=	C.O;
			shadows.back().slot		=	slot_id;
			shadows.back().C		=	C.C;
			shadows.back().M		=	mCombineR;
			shadows.back().L		=	L.source;
			shadows.back().E		=	L.energy;
#ifdef DEBUG
			shadows.back().dbg_HAT	=	p_hat;
#endif
			slot_id	++;
		}
	}

	// clear casters
	for (u32 cs=0; cs<casters.size(); cs++)
		casters_pool.push_back(casters[cs]);
	casters.clear	();
	
	// Blur
	if (bRTS)
	{
		// Fill VB
		u32							Offset;
		FVF::TL4uv* pv				= (FVF::TL4uv*) RCache.Vertex.Lock	(4,geom_Blur.stride(),Offset);
		RImplementation.ApplyBlur4	(pv,S_rt_size,S_rt_size,S_blur_kernel);
		RCache.Vertex.Unlock		(4,geom_Blur.stride());
		
		// Actual rendering (pass0, temp2real)
		RCache.set_RT				(RT->pRT	);
		RCache.set_ZB				(RImplementation.Target->pTempZB	);
		RCache.set_Shader			(sh_BlurTR	);
		RCache.set_Geometry			(geom_Blur	);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
	}
	
	// Finita la comedia
	HW.pDevice->SetRenderState				(D3DRS_ZENABLE, D3DZB_TRUE);
	Device.Statistic->RenderDUMP_Scalc.End	();
	
	RCache.set_xform_project	(Device.mProject);
	RCache.set_xform_view		(Device.mView);
}
Example #30
0
//-----------------------------------------------------------------------------
// Name: collideWithWorld()
// Desc: Recursive part of the collision response. This function is the
//       one who actually calls the collision check on the meshes
//-----------------------------------------------------------------------------
Fvector msimulator_CollideWithWorld(SCollisionData& cl, Fvector position, Fvector velocity, WORD cnt)
{
    //
    msimulator_ResolveStuck(cl,position);

    // do we need to worry ?
//	if (fsimilar(position.x,target.x,EPS_L)&&fsimilar(position.z,target.z,EPS_L))
    if (velocity.magnitude()<EPS_L)
    {
        cl.vVelocity.set(0,0,0);
        return position;
    }
    if (cnt>psCollideActDepth)				return cl.vLastSafePosition;

    Fvector ret_pos;
    Fvector destinationPoint;
    destinationPoint.add(position,velocity);

    // reset the collision package we send to the mesh
    cl.vVelocity.set	(velocity);
    cl.vSourcePoint.set	(position);
    cl.bFoundCollision	= FALSE;
    cl.bStuck			= FALSE;
    cl.fNearestDistance	= -1;

    // Check collision
    msimulator_CheckCollision	(cl);

    // check return value here, and possibly call recursively
    if (cl.bFoundCollision == FALSE  && !cl.bStuck)
    {
        // if no collision move very close to the desired destination.
        float l = velocity.magnitude();
        Fvector V;
        V.mul(velocity,(l-cl_epsilon)/l);

        // return the final position
        ret_pos.add(position,V);

        // update the last safe position for future error recovery
        cl.vLastSafePosition.set(ret_pos);
        return ret_pos;
    } else {
        // There was a collision
        // OK, first task is to move close to where we hit something :
        Fvector newSourcePoint;

        // If we are stuck, we just back up to last safe position
        if (cl.bStuck) {
            return cl.vLastSafePosition;
        }

        // only update if we are not already very close
        if (cl.fNearestDistance >= cl_epsilon) {
            Fvector V;
            V.set(velocity);
            V.set_length(cl.fNearestDistance-cl_epsilon);
            newSourcePoint.add(cl.vSourcePoint,V);
        } else {
            newSourcePoint.set(cl.vSourcePoint);
        }

        // Now we must calculate the sliding plane
        Fvector slidePlaneOrigin;
        slidePlaneOrigin.set(cl.vNearestPolygonIntersectionPoint);
        Fvector slidePlaneNormal;
        slidePlaneNormal.sub(newSourcePoint,cl.vNearestPolygonIntersectionPoint);

        // We now project the destination point onto the sliding plane
        float l = intersectRayPlane(destinationPoint, slidePlaneNormal, slidePlaneOrigin, slidePlaneNormal);

        // We can now calculate a _new destination point on the sliding plane
        Fvector newDestinationPoint;
        newDestinationPoint.mad(destinationPoint,slidePlaneNormal,l);

        // Generate the slide xr_vector, which will become our _new velocity xr_vector
        // for the next iteration
        Fvector newVelocityVector;
        newVelocityVector.sub(newDestinationPoint, cl.vNearestPolygonIntersectionPoint);

        // now we recursively call the function with the _new position and velocity
        cl.vLastSafePosition.set(position);
        return msimulator_CollideWithWorld(cl, newSourcePoint, newVelocityVector,cnt+1);
    }
}