Esempio n. 1
0
void CBulletManager::Render	()
{
#ifdef DEBUG
	//0-рикошет
	//1-застрявание пули в материале
	//2-пробивание материала
	if(g_bDrawBulletHit){
		extern FvectorVec g_hit[];
		FvectorIt it;
		u32 C[3] = {0xffff0000,0xff00ff00,0xff0000ff};
		RCache.set_xform_world(Fidentity);
		for(int i=0; i<3; ++i)
			for(it=g_hit[i].begin();it!=g_hit[i].end();++it){
				Level().debug_renderer().draw_aabb(*it,0.01f,0.01f,0.01f,C[i]);
			}
	}
#endif

	if(m_BulletsRendered.empty()) return;

	u32	vOffset			=	0	;
	u32 bullet_num		=	m_BulletsRendered.size();

	FVF::LIT	*verts		=	(FVF::LIT	*) RCache.Vertex.Lock((u32)bullet_num*8,
										tracers.sh_Geom->vb_stride,
										vOffset);
	FVF::LIT	*start		=	verts;

	for(BulletVecIt it = m_BulletsRendered.begin(); it!=m_BulletsRendered.end(); it++){
		SBullet* bullet					= &(*it);
		if(!bullet->flags.allow_tracer)	continue;
		if (!bullet->flags.skipped_frame)  continue;

		float length	= bullet->speed*float(m_dwStepTime)/1000.f;//dist.magnitude();

		if(length<m_fTracerLengthMin) continue;

		if(length>m_fTracerLengthMax)
			length			= m_fTracerLengthMax;

		float width			= m_fTracerWidth;
		float dist2segSqr = SqrDistancePointToSegment(Device.vCameraPosition, bullet->pos, Fvector().mul(bullet->dir, length));
		//---------------------------------------------
		float MaxDistSqr = 1.0f;
		float MinDistSqr = 0.09f;
		if (dist2segSqr < MaxDistSqr)
		{
			if (dist2segSqr < MinDistSqr) dist2segSqr = MinDistSqr;

			width *= _sqrt(dist2segSqr/MaxDistSqr);//*MaxDistWidth/0.08f;			
		}
		if (Device.vCameraPosition.distance_to_sqr(bullet->pos)<(length*length))
		{
			length = Device.vCameraPosition.distance_to(bullet->pos) - 0.3f;
		}
		/*
		//---------------------------------------------
		Fvector vT, v0, v1;
		vT.mad(Device.vCameraPosition, Device.vCameraDirection, _sqrt(dist2segSqr));
		v0.mad(vT, Device.vCameraTop, width*.5f);
		v1.mad(vT, Device.vCameraTop, -width*.5f);
		Fvector v0r, v1r;
		Device.mFullTransform.transform(v0r, v0);
		Device.mFullTransform.transform(v1r, v1);
		float ViewWidth = v1r.distance_to(v0r);
*/
//		float dist = _sqrt(dist2segSqr);
//		Msg("dist - [%f]; ViewWidth - %f, [%f]", dist, ViewWidth, ViewWidth*float(Device.dwHeight));
//		Msg("dist - [%f]", dist);
		//---------------------------------------------


		Fvector center;
		center.mad				(bullet->pos, bullet->dir,  -length*.5f);
		tracers.Render			(verts, bullet->pos, center, bullet->dir, length, width, bullet->m_u8ColorID);
	}

	u32 vCount					= (u32)(verts-start);
	RCache.Vertex.Unlock		(vCount,tracers.sh_Geom->vb_stride);

	if (vCount)
	{
		RCache.set_CullMode			(CULL_NONE);
		RCache.set_xform_world		(Fidentity);
		RCache.set_Shader			(tracers.sh_Tracer);
		RCache.set_Geometry			(tracers.sh_Geom);
		RCache.Render				(D3DPT_TRIANGLELIST,vOffset,0,vCount,0,vCount/2);
		RCache.set_CullMode			(CULL_CCW);
	}
}
Esempio n. 2
0
void SSceneSummary::STextureInfo::FillProp	(PropItemVec& items, LPCSTR main_pref, u32& mem_use)
{
	if (file_name.size()){
        int tex_mem			= info.MemoryUsage(*file_name);
        mem_use				+= tex_mem;
        AnsiString pref		= PrepareKey(AnsiString(main_pref).c_str(),*file_name).c_str();
        PropValue* V=0;
        V=PHelper().CreateChoose(items,PrepareKey(pref.c_str(),"Texture"), 		&file_name, smTexture); V->Owner()->Enable(FALSE);
        PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Format"),		info.FormatString());
        PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Size"), 			shared_str().printf("%d x %d x %s",info.width,info.height,info.HasAlpha()?"32b":"24b"));
        PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Memory Usage"),	shared_str().printf("%d Kb",iFloor(tex_mem/1024)));
        PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Effective Area"),shared_str().printf("%3.2f m^2",effective_area));
        PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Pixel Density"),	shared_str().printf("%3.2f p/m",_sqrt((pixel_area*info.width*info.height)/effective_area)));
/*
//. убрал из-за кол-ва > 4096 
        AnsiString tmp 		= "on demand";
        for (objinf_map_it o_it=objects.begin(); o_it!=objects.end(); o_it++){
        	tmp += AnsiString().sprintf("%s%s[%d*%3.2f]",tmp.Length()?"; ":"",o_it->first.c_str(),o_it->second.ref_count,o_it->second.area);
        }
        PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Objects"), tmp.c_str());
*/
        if (info.flags.is_any(STextureParams::flDiffuseDetail|STextureParams::flBumpDetail)){
            if (0!=info.detail_name.size()){
                V=PHelper().CreateChoose(items,PrepareKey(pref.c_str(),"Detail Texture"),	&info.detail_name,smTexture); 	V->Owner()->Enable(FALSE);
                PHelper().CreateCaption(items,PrepareKey(pref.c_str(), "Detail Scale"),		shared_str().printf("%3.2f",info.detail_scale));
            }else{
                PHelper().CreateCaption(items,PrepareKey(pref.c_str(), "Detail Texture"),	"INVALID");
                ELog.Msg(mtError,"Empty details on texture: '%s'",*file_name);
            }
        }
        if (info.bump_mode==STextureParams::tbmUse){
            if (0!=info.bump_name.size()){
                V=PHelper().CreateChoose(items,PrepareKey(pref.c_str(),"Bump Texture"),		&info.bump_name,smTexture); 	V->Owner()->Enable(FALSE);
            }else{
                PHelper().CreateCaption(items,PrepareKey(pref.c_str(), "Bump Texture"),		"INVALID");    
                ELog.Msg(mtError,"Empty bump on texture: '%s'",*file_name);
            }
        }
        ButtonValue* B 		= PHelper().CreateButton(items,PrepareKey(pref.c_str(),"Highlight Texture"), "Select,Density =,Density +,Clear", 0);
		B->OnBtnClickEvent.bind(this,&SSceneSummary::STextureInfo::OnHighlightClick);
        B->tag 				= (int)(*file_name);
    }
}
Esempio n. 3
0
// length of a vector
//
float norm(float v[3])
{
    return _sqrt(DOT(v,v));
}
Esempio n. 4
0
void objpose(mat33_t *R, vec3_t *t, int *it, real_t *obj_err, real_t *img_err,
			 bool calc_img_err, const vec3_t *_P, const vec3_t *Qp, const options_t options, const int n)
{
	int i, j;
	//vec3_array P(_P.begin(),_P.end());
	vec3_t P[n];
	memcpy(&*P, _P, n*sizeof(vec3_t));

	//const int n = (unsigned int) P.size();
	vec3_t pbar;
	vec3_array_sum(&pbar, &*P, n);
	vec3_div(&pbar, (real_t)(n));
	vec3_array_sub(&*P, &pbar, n);
	
	//vec3_array Q(Qp.begin(),Qp.end());
	vec3_t Q[n];
	memcpy(&*Q, Qp, n*sizeof(vec3_t));
	
	vec3_t ones;
	ones.v[0] = 1;
	ones.v[1] = 1;
	ones.v[2] = 1;
	const bool mask_z[3] = {0,0,1};
	vec3_array_set(&*Q, &ones, mask_z, n);
	
	//mat33_array F;
	//F.resize(n);
	mat33_t F[n];
	
	vec3_t V;
	for(i=0; i<n; i++)
	{
		V.v[0] = Q[i].v[0] / Q[i].v[2];
		V.v[1] = Q[i].v[1] / Q[i].v[2];
		V.v[2] = 1.0;
		mat33_t _m;
		vec3_mul_vec3trans(&_m, &V, &V);
		mat33_div(&_m, vec3trans_mul_vec3(&V,&V));
		F[i] = _m;
	}

	mat33_t tFactor;
	
	mat33_t _m1,_m2,_m3;
	mat33_eye(&_m1);
	mat33_array_sum(&_m2, &*F, n);
	mat33_div(&_m2, (real_t)(n));
	mat33_sub_mat2(&_m3, &_m1, &_m2);
	mat33_inv(&tFactor, &_m3);
	mat33_div(&tFactor, (real_t)(n));

	*it = 0;
	int initR_approximate = mat33_all_zeros(&options.initR);
	mat33_t Ri;
	vec3_t ti;
	
	//vec3_array Qi;
	//Qi.resize(n);
	vec3_t Qi[n];
	
	real_t old_err = 0.0, new_err = 0.0;

	// ----------------------------------------------------------------------------------------
	if(initR_approximate == 0)
	{
		mat33_copy(&Ri, &options.initR);
		vec3_t _sum;
		vec3_t _v1, _v2;
		mat33_t _m1,_m2;
		vec3_clear(&_sum);
		for(j=0; j<n; j++)
		{
			mat33_eye(&_m1);
			mat33_sub_mat2(&_m2, &F[j], &_m1);
			vec3_mult_mat(&_v1, &Ri, &P[j]);
			vec3_mult_mat(&_v2, &_m2, &_v1);
			vec3_add_vec(&_sum, &_v2);
		}
		vec3_mult_mat(&ti,&tFactor,&_sum);
		xform(&*Qi, &*P, &Ri, &ti, n);
		old_err = 0;
		vec3_t _v;
		for(j=0; j<n; j++)
		{
			mat33_eye(&_m1);
			mat33_sub_mat2(&_m2, &F[j], &_m1);
			vec3_mult_mat(&_v, &_m2, &Qi[j]);
			old_err += vec3_dot(&_v, &_v);
		}
	// ----------------------------------------------------------------------------------------
	}
	else
	{
		abskernel(&Ri, &ti, &*Qi, &old_err, &*P, &*Q, &*F, &tFactor, n);
		*it = 1;
	}
	// ----------------------------------------------------------------------------------------

	abskernel(&Ri, &ti, &*Qi, &new_err, &*P, &*Qi, &*F, &tFactor, n);
	*it = *it + 1;

	while((_abs((old_err-new_err)/old_err) > options.tol) && (new_err > options.epsilon) &&
		  (options.max_iter == 0 || *it < options.max_iter))
	{
		old_err = new_err;
		abskernel(&Ri, &ti, &*Qi, &new_err, &*P, &*Qi, &*F, &tFactor, n);
		*it = *it + 1;
	}


	mat33_copy(R, &Ri);
	vec3_copy(t, &ti);
	*obj_err = _sqrt(new_err/(real_t)(n));

	if(calc_img_err == 1)
	{
		//vec3_array Qproj;
		//Qproj.resize(n);
		vec3_t Qproj[n];
		
		xformproj(&*Qproj, &*P, &Ri, &ti, n);
		*img_err = 0;

		vec3_t _v;
		for(j=0; j<n; j++)
		{
			vec3_sub_vec2(&_v, &Qproj[j], &Qp[j]);
			*img_err += vec3_dot(&_v, &_v);
		}
		*img_err = _sqrt(*img_err/(real_t)(n));
	}

	if(t->v[2] < 0)
	{
		mat33_mult(R, -1.0);
		vec3_mult(t, -1.0);
	}

	vec3_t _ts;
	vec3_mult_mat(&_ts, &Ri, &pbar);
	vec3_sub_vec(t, &_ts);
}
void CRenderTarget::accum_direct		(u32 sub_phase)
{
	// Choose normal code-path or filtered
	phase_accumulator					();
	if (RImplementation.o.sunfilter)	{
		accum_direct_f	(sub_phase);
		return			;
	}

	// *** assume accumulator setted up ***
	light*			fuckingsun			= (light*)RImplementation.Lights.sun_adapted._get()	;

	// Common calc for quad-rendering
	u32		Offset;
	u32		C					= color_rgba	(255,255,255,255);
	float	_w					= float			(Device.dwWidth);
	float	_h					= float			(Device.dwHeight);
	Fvector2					p0,p1;
	p0.set						(.5f/_w, .5f/_h);
	p1.set						((_w+.5f)/_w, (_h+.5f)/_h );
	float	d_Z	= EPS_S, d_W = 1.f;

	// Common constants (light-related)
	Fvector		L_dir,L_clr;	float L_spec;
	L_clr.set					(fuckingsun->color.r,fuckingsun->color.g,fuckingsun->color.b);
	L_spec						= u_diffuse2s	(L_clr);
	Device.mView.transform_dir	(L_dir,fuckingsun->direction);
	L_dir.normalize				();

	// Perform masking (only once - on the first/near phase)
	RCache.set_CullMode			(CULL_NONE	);
	if (SE_SUN_NEAR==sub_phase)	//.
	{
		// Fill vertex buffer
		FVF::TL* pv					= (FVF::TL*)	RCache.Vertex.Lock	(4,g_combine->vb_stride,Offset);
		pv->set						(EPS,			float(_h+EPS),	d_Z,	d_W, C, p0.x, p1.y);	pv++;
		pv->set						(EPS,			EPS,			d_Z,	d_W, C, p0.x, p0.y);	pv++;
		pv->set						(float(_w+EPS),	float(_h+EPS),	d_Z,	d_W, C, p1.x, p1.y);	pv++;
		pv->set						(float(_w+EPS),	EPS,			d_Z,	d_W, C, p1.x, p0.y);	pv++;
		RCache.Vertex.Unlock		(4,g_combine->vb_stride);
		RCache.set_Geometry			(g_combine);

		// setup
		float	intensity			= 0.3f*fuckingsun->color.r + 0.48f*fuckingsun->color.g + 0.22f*fuckingsun->color.b;
		Fvector	dir					= L_dir;
				dir.normalize().mul	(- _sqrt(intensity+EPS));
		RCache.set_Element			(s_accum_mask->E[SE_MASK_DIRECT]);		// masker
		RCache.set_c				("Ldynamic_dir",		dir.x,dir.y,dir.z,0		);

		// if (stencil>=1 && aref_pass)	stencil = light_id
		RCache.set_ColorWriteEnable	(FALSE		);
		RCache.set_Stencil			(TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0x01,0xff,D3DSTENCILOP_KEEP,D3DSTENCILOP_REPLACE,D3DSTENCILOP_KEEP);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
	}

	// recalculate d_Z, to perform depth-clipping
	Fvector	center_pt;			center_pt.mad	(Device.vCameraPosition,Device.vCameraDirection,ps_r2_sun_near);
	Device.mFullTransform.transform(center_pt)	;
	d_Z							= center_pt.z	;

	// nv-stencil recompression
	if (RImplementation.o.nvstencil  && (SE_SUN_NEAR==sub_phase))	u_stencil_optimize();	//. driver bug?

	// Perform lighting
	{
		phase_accumulator					()	;
		RCache.set_CullMode					(CULL_NONE);
		RCache.set_ColorWriteEnable			()	;

		// texture adjustment matrix
		float			fTexelOffs			= (.5f / float(RImplementation.o.smapsize));
		float			fRange				= (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_scale:ps_r2_sun_depth_far_scale;
		float			fBias				= (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias;
		Fmatrix			m_TexelAdjust		= 
		{
			0.5f,				0.0f,				0.0f,			0.0f,
			0.0f,				-0.5f,				0.0f,			0.0f,
			0.0f,				0.0f,				fRange,			0.0f,
			0.5f + fTexelOffs,	0.5f + fTexelOffs,	fBias,			1.0f
		};

		// compute xforms
		FPU::m64r			();
		Fmatrix				xf_invview;		xf_invview.invert	(Device.mView)	;

		// shadow xform
		Fmatrix				m_shadow;
		{
			Fmatrix			xf_project;		xf_project.mul		(m_TexelAdjust,fuckingsun->X.D.combine);
			m_shadow.mul	(xf_project,	xf_invview);

			// tsm-bias
			if ( (SE_SUN_FAR == sub_phase) && (RImplementation.o.HW_smap) )
			{
				Fvector		bias;	bias.mul		(L_dir,ps_r2_sun_tsm_bias);
				Fmatrix		bias_t;	bias_t.translate(bias);
				m_shadow.mulB_44	(bias_t);
			}
			FPU::m24r		();
		}

		// clouds xform
		Fmatrix				m_clouds_shadow;
		{
			static	float	w_shift		= 0;
			Fmatrix			m_xform;
			Fvector			direction	= fuckingsun->direction	;
			float	w_dir				= g_pGamePersistent->Environment().CurrentEnv.wind_direction	;
			//float	w_speed				= g_pGamePersistent->Environment().CurrentEnv.wind_velocity	;
			Fvector			normal	;	normal.setHP(w_dir,0);
							w_shift		+=	0.003f*Device.fTimeDelta;
			Fvector			position;	position.set(0,0,0);
			m_xform.build_camera_dir	(position,direction,normal)	;
			Fvector			localnormal;m_xform.transform_dir(localnormal,normal); localnormal.normalize();
			m_clouds_shadow.mul			(m_xform,xf_invview)		;
			m_xform.scale				(0.002f,0.002f,1.f)			;
			m_clouds_shadow.mulA_44		(m_xform)					;
			m_xform.translate			(localnormal.mul(w_shift))	;
			m_clouds_shadow.mulA_44		(m_xform)					;
		}

		// Make jitter texture
		Fvector2					j0,j1;
		float	scale_X				= float(Device.dwWidth)	/ float(TEX_jitter);
		//float	scale_Y				= float(Device.dwHeight)/ float(TEX_jitter);
		float	offset				= (.5f / float(TEX_jitter));
		j0.set						(offset,offset);
		j1.set						(scale_X,scale_X).add(offset);

		// Fill vertex buffer
		FVF::TL2uv* pv				= (FVF::TL2uv*) RCache.Vertex.Lock	(4,g_combine_2UV->vb_stride,Offset);
		pv->set						(EPS,			float(_h+EPS),	d_Z,	d_W, C, p0.x, p1.y, j0.x, j1.y);	pv++;
		pv->set						(EPS,			EPS,			d_Z,	d_W, C, p0.x, p0.y, j0.x, j0.y);	pv++;
		pv->set						(float(_w+EPS),	float(_h+EPS),	d_Z,	d_W, C, p1.x, p1.y, j1.x, j1.y);	pv++;
		pv->set						(float(_w+EPS),	EPS,			d_Z,	d_W, C, p1.x, p0.y, j1.x, j0.y);	pv++;
		RCache.Vertex.Unlock		(4,g_combine_2UV->vb_stride);
		RCache.set_Geometry			(g_combine_2UV);

		// setup
		RCache.set_Element			(s_accum_direct->E[sub_phase]);
		RCache.set_c				("Ldynamic_dir",		L_dir.x,L_dir.y,L_dir.z,0		);
		RCache.set_c				("Ldynamic_color",		L_clr.x,L_clr.y,L_clr.z,L_spec	);
		RCache.set_c				("m_shadow",			m_shadow						);
		RCache.set_c				("m_sunmask",			m_clouds_shadow					);
		
		// nv-DBT
		if (RImplementation.o.nvdbt && ps_r2_ls_flags.test(R2FLAG_USE_NVDBT))	{
			float zMin,zMax;
			if (SE_SUN_NEAR==sub_phase)	{
				zMin = 0;
				zMax = ps_r2_sun_near;
			} else {
				extern float	OLES_SUN_LIMIT_27_01_07;
				zMin = ps_r2_sun_near;
				zMax = OLES_SUN_LIMIT_27_01_07;
			}

			center_pt.mad(Device.vCameraPosition,Device.vCameraDirection,zMin);	Device.mFullTransform.transform	(center_pt);
			zMin = center_pt.z	;

			center_pt.mad(Device.vCameraPosition,Device.vCameraDirection,zMax);	Device.mFullTransform.transform	(center_pt);
			zMax = center_pt.z	;

			// enable cheat
			HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_X,MAKEFOURCC('N','V','D','B'));
			HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_Z,*(DWORD*)&zMin);
			HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_W,*(DWORD*)&zMax); 

			// z-test always
			HW.pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
			HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
		}

		// Fetch4 : enable
		if (RImplementation.o.HW_smap_FETCH4)	{
			//. we hacked the shader to force smap on S0
#			define FOURCC_GET4  MAKEFOURCC('G','E','T','4') 
			HW.pDevice->SetSamplerState	( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4 );
		}

		// setup stencil
		RCache.set_Stencil			(TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);

		// Fetch4 : disable
		if (RImplementation.o.HW_smap_FETCH4)	{
			//. we hacked the shader to force smap on S0
#			define FOURCC_GET1  MAKEFOURCC('G','E','T','1') 
			HW.pDevice->SetSamplerState	( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1 );
		}

		// disable depth bounds
		if (RImplementation.o.nvdbt && ps_r2_ls_flags.test(R2FLAG_USE_NVDBT))	HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_X,0);
	}
}
Esempio n. 6
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						;
			}
		}
	}
}
Esempio n. 7
0
void CSector::traverse			(CFrustum &F, _scissor& R_scissor)
{
	// Register traversal process
	if (r_marker	!=	PortalTraverser.i_marker)	{
		r_marker							=	PortalTraverser.i_marker;
		PortalTraverser.r_sectors.push_back	(this);
		r_frustums.clear					();
		r_scissors.clear					();
	}
	r_frustums.push_back		(F);
	r_scissors.push_back		(R_scissor);

	// Search visible portals and go through them
	sPoly	S,D;
	for	(u32 I=0; I<m_portals.size(); I++)
	{
		if (m_portals[I]->marker == PortalTraverser.i_marker) continue;

		CPortal* PORTAL = m_portals[I];
		CSector* pSector;

		// Select sector (allow intersecting portals to be finely classified)
		if (PORTAL->bDualRender) {
			pSector = PORTAL->getSector						(this);
		} else {
			pSector = PORTAL->getSectorBack					(PortalTraverser.i_vBase);
			if (pSector==this)								continue;
			if (pSector==PortalTraverser.i_start)			continue;
		}

		// Early-out sphere
		if (!F.testSphere_dirty(PORTAL->S.P,PORTAL->S.R))	continue;

		// SSA	(if required)
		if (PortalTraverser.i_options&CPortalTraverser::VQ_SSA)
		{
			Fvector				dir2portal;
			dir2portal.sub		(PORTAL->S.P,	PortalTraverser.i_vBase);
			float R				=	PORTAL->S.R	;
			float distSQ		=	dir2portal.square_magnitude();
			float ssa			=	R*R/distSQ;
			dir2portal.div		(_sqrt(distSQ));
			ssa					*=	_abs(PORTAL->P.n.dotproduct(dir2portal));
			if (ssa<r_ssaDISCARD)	continue;

			if (PortalTraverser.i_options&CPortalTraverser::VQ_FADE)	{
				if (ssa<r_ssaLOD_A)	PortalTraverser.fade_portal			(PORTAL,ssa);
				if (ssa<r_ssaLOD_B)	continue							;
			}
		}

		// Clip by frustum
		svector<Fvector,8>&	POLY = PORTAL->getPoly();
		S.assign			(&*POLY.begin(),POLY.size()); D.clear();
		sPoly* P			= F.ClipPoly(S,D);
		if (0==P)			continue;

		// Scissor and optimized HOM-testing
		_scissor			scissor	;
		if (PortalTraverser.i_options&CPortalTraverser::VQ_SCISSOR && (!PORTAL->bDualRender))
		{
			// Build scissor rectangle in projection-space
			Fbox2	bb;	bb.invalidate(); float depth = flt_max;
			sPoly&	p	= *P;
			for		(u32 vit=0; vit<p.size(); vit++)	{
				Fvector4	t;	
				Fmatrix&	M	= PortalTraverser.i_mXFORM_01;
				Fvector&	v	= p[vit];

				t.x = v.x*M._11 + v.y*M._21 + v.z*M._31 + M._41;
				t.y = v.x*M._12 + v.y*M._22 + v.z*M._32 + M._42;
				t.z = v.x*M._13 + v.y*M._23 + v.z*M._33 + M._43;
				t.w = v.x*M._14 + v.y*M._24 + v.z*M._34 + M._44;
				t.mul	(1.f/t.w);

				if (t.x < bb.min.x)	bb.min.x	= t.x; 
				if (t.x > bb.max.x) bb.max.x	= t.x;
				if (t.y < bb.min.y)	bb.min.y	= t.y; 
				if (t.y > bb.max.y) bb.max.y	= t.y;
				if (t.z < depth)	depth		= t.z;
			}
			// Msg	("bb(%s): (%f,%f)-(%f,%f), d=%f", PORTAL->bDualRender?"true":"false",bb.min.x, bb.min.y, bb.max.x, bb.max.y,depth);
			if (depth<EPS)	{
				scissor	= R_scissor;

				// Cull by HOM (slower algo)
				if  (
					(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
					(!RImplementation.HOM.visible(*P))
					)	continue;
			} else {
				// perform intersection (this is just to be sure, it is probably clipped in 3D already)
				if (bb.min.x > R_scissor.min.x)	scissor.min.x = bb.min.x; else scissor.min.x = R_scissor.min.x;
				if (bb.min.y > R_scissor.min.y)	scissor.min.y = bb.min.y; else scissor.min.y = R_scissor.min.y;
				if (bb.max.x < R_scissor.max.x) scissor.max.x = bb.max.x; else scissor.max.x = R_scissor.max.x;
				if (bb.max.y < R_scissor.max.y) scissor.max.y = bb.max.y; else scissor.max.y = R_scissor.max.y;
				scissor.depth	= depth;

				// Msg	("scissor: (%f,%f)-(%f,%f)", scissor.min.x, scissor.min.y, scissor.max.x, scissor.max.y);
				// Check if box is non-empty
				if (scissor.min.x >= scissor.max.x)	continue;
				if (scissor.min.y >= scissor.max.y)	continue;

				// Cull by HOM (faster algo)
				if  (
					(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
					(!RImplementation.HOM.visible(scissor,depth))
					)	continue;
			}
		} else {
			scissor	= R_scissor;

			// Cull by HOM (slower algo)
			if  (
				(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
				(!RImplementation.HOM.visible(*P))
				)	continue;
		}

		// Create _new_ frustum and recurse
		CFrustum				Clip;
		Clip.CreateFromPortal	(P, PORTAL->P.n, PortalTraverser.i_vBase,PortalTraverser.i_mXFORM);
		PORTAL->marker			= PortalTraverser.i_marker;
		PORTAL->bDualRender		= FALSE;
		pSector->traverse		(Clip,scissor);
	}
}
Esempio n. 8
0
int dcTriListCollider::dSortedTriCyl (
				   const dReal* triSideAx0,const dReal* triSideAx1,
				   const dReal* triAx,
				   //const dReal* v0,
				   //const dReal* v1,
				   //const dReal* v2,
				   CDB::TRI* T,
				   dReal dist,
				   dxGeom *o1, dxGeom *o2,
				   int flags, dContactGeom *contact, int skip
				   )
{
	
	VERIFY (dGeomGetClass(o1)== dCylinderClassUser);

	const dReal *R = dGeomGetRotation(o1);
	const dReal* p=dGeomGetPosition(o1);
	dReal radius;
	dReal hlz;
	dGeomCylinderGetParams(o1,&radius,&hlz);
	hlz/=2.f;

	// find number of contacts requested
	int maxc = flags & NUMC_MASK;
	if (maxc < 1) maxc = 1;
	if (maxc > 3) maxc = 3;	// no more than 3 contacts per box allowed
	
	dReal signum, outDepth,cos1,sin1;
	////////////////////////////////////////////////////////////////////////////
	//sepparation along tri plane normal;///////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////


	//cos0=dDOT14(triAx,R+0);
	cos1=dFabs(dDOT14(triAx,R+1));
	//cos2=dDOT14(triAx,R+2);

	//sin1=_sqrt(cos0*cos0+cos2*cos2);

	////////////////////////
	//another way //////////
	cos1=cos1<REAL(1.) ? cos1 : REAL(1.); //cos1 may slightly exeed 1.f
	sin1=_sqrt(REAL(1.)-cos1*cos1);
	//////////////////////////////

	dReal sidePr=cos1*hlz+sin1*radius;

	
	if(dist>0.f) 
			return 0;
	dReal depth=sidePr-dist;
	outDepth=depth;
	signum=-1.f;

	int code=0;
	if(depth<0.f) return 0;

	dVector3 norm;
	unsigned int ret=0;
	dVector3 pos;
	if(code==0){
		norm[0]=triAx[0]*signum;
		norm[1]=triAx[1]*signum;
		norm[2]=triAx[2]*signum;


		dReal Q1 = signum*dDOT14(triAx,R+0);
		dReal Q2 = signum*dDOT14(triAx,R+1);
		dReal Q3 = signum*dDOT14(triAx,R+2);
		dReal factor =_sqrt(Q1*Q1+Q3*Q3);
		dReal	C1,C3;
		dReal centerDepth;//depth in the cirle centre
		if(factor>0.f)
		{
			C1=Q1/factor;
			C3=Q3/factor;

		}
		else
		{
			C1=1.f;
			C3=0.f;

		}

		dReal A1 = radius *		C1;//cosinus
		dReal A2 = hlz*Q2;
		dReal A3 = radius *		C3;//sinus 

		if(factor>0.f) centerDepth=outDepth-A1*Q1-A3*Q3; else centerDepth=outDepth;

		pos[0]=p[0];
		pos[1]=p[1];
		pos[2]=p[2];

		pos[0]+= A2>0 ? hlz*R[1]:-hlz*R[1];
		pos[1]+= A2>0 ? hlz*R[5]:-hlz*R[5];
		pos[2]+= A2>0 ? hlz*R[9]:-hlz*R[9];




		ret=0;
		contact->pos[0] = pos[0]+A1*R[0]+A3*R[2];
		contact->pos[1] = pos[1]+A1*R[4]+A3*R[6];
		contact->pos[2] = pos[2]+A1*R[8]+A3*R[10];

			{
				contact->depth = outDepth;
				ret=1;
			}

			if(dFabs(Q2)>M_SQRT1_2){

				A1=(-C1*M_COS_PI_3-C3*M_SIN_PI_3)*radius;
				A3=(-C3*M_COS_PI_3+C1*M_SIN_PI_3)*radius;
				CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2];
				CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6];
				CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10];
				CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3;

				if(CONTACT(contact,ret*skip)->depth>0.f)++ret;

				A1=(-C1*M_COS_PI_3+C3*M_SIN_PI_3)*radius;
				A3=(-C3*M_COS_PI_3-C1*M_SIN_PI_3)*radius;
				CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2];
				CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6];
				CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10];
				CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3;

				if(CONTACT(contact,ret*skip)->depth>0.f)++ret;
			} else {

				CONTACT(contact,ret*skip)->pos[0]=contact->pos[0]-2.f*(A2>0 ? hlz*R[1]:-hlz*R[1]);
				CONTACT(contact,ret*skip)->pos[1]=contact->pos[1]-2.f*(A2>0 ? hlz*R[5]:-hlz*R[5]);
				CONTACT(contact,ret*skip)->pos[2]=contact->pos[2]-2.f*(A2>0 ? hlz*R[9]:-hlz*R[9]);
				CONTACT(contact,ret*skip)->depth=outDepth-Q2*2.f*A2;

				if(CONTACT(contact,ret*skip)->depth>0.f)++ret;
			}
	}

	if((int)ret>maxc) ret=(unsigned int)maxc;

	for (unsigned int i=0; i<ret; ++i) {
		CONTACT(contact,i*skip)->g1 = const_cast<dxGeom*> (o2);
		CONTACT(contact,i*skip)->g2 = const_cast<dxGeom*> (o1);
		CONTACT(contact,i*skip)->normal[0] = norm[0];
		CONTACT(contact,i*skip)->normal[1] = norm[1];
		CONTACT(contact,i*skip)->normal[2] = norm[2];
		SURFACE(contact,i*skip)->mode=T->material;
	}
	if(ret&&dGeomGetUserData(o1)->callback)dGeomGetUserData(o1)->callback(T,contact);
	return ret;  
}
Esempio n. 9
0
void CLevelGraph::draw_nodes	()
{
	CGameObject*	O	= smart_cast<CGameObject*> (Level().CurrentEntity());
	Fvector	POSITION	= O->Position();
	POSITION.y += 0.5f;

	// display
	Fvector P			= POSITION;

//	CPosition			Local;
//	vertex_position		(Local,P);

	u32 ID				= O->ai_location().level_vertex_id();

	CGameFont* F		= HUD().Font().pFontDI;
	F->SetHeightI		(.02f);
	F->OutI				(0.f,0.5f,"%f,%f,%f",VPUSH(P));
//	float				x,z;
//	unpack_xz			(Local,x,z);
//	F->Out				(0.f,0.55f,"%3d,%4d,%3d -> %d",	iFloor(x),iFloor(Local.y()),iFloor(z),u32(ID));

	svector<u32,128>	linked;
	{
		const_iterator	i,e;
		begin			(ID,i,e);
		for(; i != e; ++i)
			linked.push_back(value(ID,i));
	}

	// render
	float	sc		= header().cell_size()/16;
	float	st		= 0.98f*header().cell_size()/2;
	float	tt		= 0.01f;

	Fvector	DUP;		DUP.set(0,1,0);

	RCache.set_Shader	(sh_debug);
	F->SetColor			(color_rgba(255,255,255,255));

	// если включён ai_dbg_frustum раскрасить ноды по light
	// иначе раскрашивать по cover
	bool			b_light = false;
	
	//////////////////////////////////////////////////////////////////////////
	Fvector min_position,max_position;
	max_position = min_position = Device.vCameraPosition;
	min_position.sub(30.f);
	max_position.add(30.f);
	
	CLevelGraph::const_vertex_iterator	 I, E;
	if (valid_vertex_position(min_position))
		I = std::lower_bound(begin(),end(),vertex_position(min_position).xz());
	else
		I = begin();

	if (valid_vertex_position(max_position)) {
		E = std::upper_bound(begin(),end(),vertex_position(max_position).xz());
		if (E != end()) ++E;
	}
	else
		E = end();

	//////////////////////////////////////////////////////////////////////////

	for ( ; I != E; ++I)
	{
		const CLevelGraph::CVertex&	N	= *I;
		Fvector			PC;
		PC				= vertex_position(N);

		u32 Nid			= vertex_id(I);

		if (Device.vCameraPosition.distance_to(PC)>30) continue;

		float			sr	= header().cell_size();
		if (::Render->ViewBase.testSphere_dirty(PC,sr)) {
			
			u32	LL = ((b_light) ?	iFloor(float(N.light())/15.f*255.f) : 
									iFloor(vertex_cover(I)/4*255.f));
			
			u32	CC		= D3DCOLOR_XRGB(0,0,255);
			u32	CT		= D3DCOLOR_XRGB(LL,LL,LL);
			u32	CH		= D3DCOLOR_XRGB(0,128,0);

			BOOL	bHL		= FALSE;
			if (Nid==u32(ID))	{ bHL = TRUE; CT = D3DCOLOR_XRGB(0,255,0); }
			else {
				for (u32 t=0; t<linked.size(); ++t) {
					if (linked[t]==Nid) { bHL = TRUE; CT = CH; break; }
				}
			}

			// unpack plane
			Fplane PL; Fvector vNorm;
			pvDecompress(vNorm,N.plane());
			PL.build	(PC,vNorm);

			// create vertices
			Fvector		v,v1,v2,v3,v4;
			v.set(PC.x-st,PC.y,PC.z-st);	PL.intersectRayPoint(v,DUP,v1);	v1.mad(v1,PL.n,tt);	// minX,minZ
			v.set(PC.x+st,PC.y,PC.z-st);	PL.intersectRayPoint(v,DUP,v2);	v2.mad(v2,PL.n,tt);	// maxX,minZ
			v.set(PC.x+st,PC.y,PC.z+st);	PL.intersectRayPoint(v,DUP,v3);	v3.mad(v3,PL.n,tt);	// maxX,maxZ
			v.set(PC.x-st,PC.y,PC.z+st);	PL.intersectRayPoint(v,DUP,v4);	v4.mad(v4,PL.n,tt);	// minX,maxZ

			// render quad
			RCache.dbg_DrawTRI	(Fidentity,v3,v2,v1,CT);
			RCache.dbg_DrawTRI	(Fidentity,v1,v4,v3,CT);

			// render center
			Level().debug_renderer().draw_aabb	(PC,sc,sc,sc,CC);

			// render id
			if (bHL) {
				Fvector		T;
				Fvector4	S;
				T.set		(PC); T.y+=0.3f;
				Device.mFullTransform.transform	(S,T);
				if (S.z < 0 || S.z < 0)												continue;
				if (S.x < -1.f || S.x > 1.f || S.y<-1.f || S.x>1.f)					continue;
				F->SetHeightI	(0.05f/_sqrt(_abs(S.w)));
				F->SetColor	(0xffffffff);
				F->OutI		(S.x,-S.y,"~%d",Nid);
			}
		}
	}
}
Esempio n. 10
0
void PS::CPEDef::CollisionCutoffOnDraw(PropValue* sender, xr_string& draw_val)
{    
	FloatValue* V	= dynamic_cast<FloatValue*>(sender); VERIFY(V);
	draw_sprintf(draw_val,_sqrt(V->GetValue()),V->dec);
}
Esempio n. 11
0
int dcTriListCollider::dTriCyl (
						const dReal* v0,const dReal* v1,const dReal* v2,
						Triangle* T,
						dxGeom *o1, dxGeom *o2,
						int flags, dContactGeom *contact, int skip
						)
{

 // VERIFY (skip >= (int)sizeof(dContactGeom));
  VERIFY (dGeomGetClass(o1)== dCylinderClassUser);
  

  
  
  const dReal *R = dGeomGetRotation(o1);
  const dReal* p=dGeomGetPosition(o1);
  dReal radius;
  dReal hlz;
  dGeomCylinderGetParams(o1,&radius,&hlz);
  hlz/=2.f;

    // find number of contacts requested
  int maxc = flags & NUMC_MASK;
  if (maxc < 1) maxc = 1;
  if (maxc > 3) maxc = 3;	// no more than 3 contacts per box allowed


  const dVector3 &triAx=T->norm;
  dVector3 triSideAx0={T->side0[0],T->side0[1],T->side0[2]}; //{v1[0]-v0[0],v1[1]-v0[1],v1[2]-v0[2]};
  dVector3 triSideAx1={T->side1[0],T->side1[1],T->side1[2]}; //{v2[0]-v1[0],v2[1]-v1[1],v2[2]-v1[2]};
  dVector3 triSideAx2={v0[0]-v2[0],v0[1]-v2[1],v0[2]-v2[2]};
  //dCROSS(triAx,=,triSideAx0,triSideAx1);
  int code=0;
  dReal signum, outDepth,cos0,cos1,cos2,sin1;
////////////////////////////////////////////////////////////////////////////
//sepparation along tri plane normal;///////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//accurate_normalize(triAx);

//cos0=dDOT14(triAx,R+0);
cos1=dFabs(dDOT14(triAx,R+1));
//cos2=dDOT14(triAx,R+2);

//sin1=_sqrt(cos0*cos0+cos2*cos2);

////////////////////////
//another way //////////
cos1=cos1<REAL(1.) ? cos1 : REAL(1.); //cos1 may slightly exeed 1.f
sin1=_sqrt(REAL(1.)-cos1*cos1);
//////////////////////////////

dReal sidePr=cos1*hlz+sin1*radius;

dReal dist=-T->dist; //dDOT(triAx,v0)-dDOT(triAx,p);
if(dist>0.f) RETURN0;
dReal depth=sidePr-dFabs(dist);
outDepth=depth;
signum=dist>0.f ? 1.f : -1.f;

code=0;
if(depth<0.f) RETURN0;

dReal depth0,depth1,depth2,dist0,dist1,dist2;
bool isPdist0,isPdist1,isPdist2;
bool testV0,testV1,testV2;
bool sideTestV00,sideTestV01,sideTestV02;
bool sideTestV10,sideTestV11,sideTestV12;
bool sideTestV20,sideTestV21,sideTestV22;


//////////////////////////////////////////////////////////////////////////////
//cylinder axis - one of the triangle vertexes touches cylinder's flat surface
//////////////////////////////////////////////////////////////////////////////
dist0=dDOT14(v0,R+1)-dDOT14(p,R+1);
dist1=dDOT14(v1,R+1)-dDOT14(p,R+1);
dist2=dDOT14(v2,R+1)-dDOT14(p,R+1);

isPdist0=dist0>0.f;
isPdist1=dist1>0.f;
isPdist2=dist2>0.f;

depth0=hlz-dFabs(dist0);
depth1=hlz-dFabs(dist1);
depth2=hlz-dFabs(dist2);

testV0=depth0>0.f;
testV1=depth1>0.f;
testV2=depth2>0.f;

if(isPdist0==isPdist1 && isPdist1== isPdist2) //(here and lower) check the tryangle is on one side of the cylinder
   
{
if(depth0>depth1) 
		if(depth0>depth2) 	
			if(testV0){
				if(depth0<outDepth) 
					{
					signum= isPdist0 ? 1.f : -1.f;
					outDepth=depth0;			
					code=1;
					}
				}
			else 
				RETURN0;
		else
			if(testV2){
				if(depth2<outDepth) 
					{
					outDepth=depth2;
					signum= isPdist2 ? 1.f : -1.f;
					code=3;
					}
			}
			else 
				RETURN0;
else
		if(depth1>depth2)
			if(testV1){
				if(depth1<outDepth) 
					{
					outDepth=depth1;
					signum= isPdist1 ? 1.f : -1.f;
					code=2;
					}
			}
			else 
				RETURN0;

		else
			if(testV2){
				if(depth2<outDepth) 
					{
					outDepth=depth2;
					signum= isPdist2 ? 1.f : -1.f;
					code=2;
					}
			}
			else RETURN0;
}


dVector3 axis,outAx;
dReal posProj;
dReal pointDepth=0.f;


#define TEST(vx,ox1,ox2,c)	\
	{\
	posProj=dDOT14(v##vx,R+1)-dDOT14(p,R+1);\
\
	axis[0]=v##vx[0]-p[0]-R[1]*posProj;\
	axis[1]=v##vx[1]-p[1]-R[5]*posProj;\
	axis[2]=v##vx[2]-p[2]-R[9]*posProj;\
\
	accurate_normalize(axis);\
\
\
	dist0=dDOT(v0,axis)-dDOT(p,axis);\
	dist1=dDOT(v1,axis)-dDOT(p,axis);\
	dist2=dDOT(v2,axis)-dDOT(p,axis);\
\
	isPdist0=dist0>0.f;\
	isPdist1=dist1>0.f;\
	isPdist2=dist2>0.f;\
\
	depth0=radius-dFabs(dist0);\
	depth1=radius-dFabs(dist1);\
	depth2=radius-dFabs(dist2);\
\
	sideTestV##vx##0=depth0>0.f;\
	sideTestV##vx##1=depth1>0.f;\
	sideTestV##vx##2=depth2>0.f;\
\
	if(isPdist0==isPdist1 && isPdist1== isPdist2)\
\
	{\
	if(sideTestV##vx##0||sideTestV##vx##1||sideTestV##vx##2){\
	if(!(depth##vx<depth##ox1 || depth##vx<depth##ox2))\
					{\
						if(depth##vx<outDepth && depth##vx > pointDepth)\
							{\
							pointDepth=depth##vx;\
							signum= isPdist##vx ? 1.f : -1.f;\
							outAx[0]=axis[0];\
							outAx[1]=axis[1];\
							outAx[2]=axis[2];\
							code=c;\
							}\
					}\
	}\
	else RETURN0;\
			\
\
\
	}\
}

if(testV0) TEST(0,1,2,4)
if(testV1 ) TEST(1,2,0,5)
//&& sideTestV01
if(testV2 ) TEST(2,0,1,6)
//&& sideTestV02 && sideTestV12
#undef TEST

dVector3 tpos,pos;
if(code>3) outDepth=pointDepth; //deepest vertex axis used if its depth less than outDepth
//else{
//bool outV0=!(testV0&&sideTestV00&&sideTestV10&&sideTestV20);
//bool outV1=!(testV1&&sideTestV01&&sideTestV11&&sideTestV21);
//bool outV2=!(testV2&&sideTestV02&&sideTestV12&&sideTestV22);
bool outV0=true;
bool outV1=true;
bool outV2=true;
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
///crosses between triangle sides and cylinder axis//////////////////////////
/////////////////////////////////////////////////////////////////////////////
#define TEST(ax,nx,ox,c)	if(cylinderCrossesLine(p,R+1,hlz,v##ax,v##nx,triSideAx##ax,tpos))	{\
	dCROSS114(axis,=,triSideAx##ax,R+1);\
	accurate_normalize(axis);\
	dist##ax=dDOT(v##ax,axis)-dDOT(p,axis);\
	dist##ox=dDOT(v##ox,axis)-dDOT(p,axis);\
\
	isPdist##ax=dist##ax>0.f;\
	isPdist##ox=dist##ox>0.f;\
\
	if(isPdist##ax == isPdist##ox)\
{\
depth##ax=radius-dFabs(dist##ax);\
depth##ox=radius-dFabs(dist##ox);\
	\
			if(depth##ax>0.f){\
				if(depth##ax<=outDepth && depth##ax>=depth##ox) \
					{\
						outDepth=depth##ax;\
						signum= isPdist##ax ? 1.f : -1.f;\
						outAx[0]=axis[0];\
						outAx[1]=axis[1];\
						outAx[2]=axis[2];\
						pos[0]=tpos[0];\
						pos[1]=tpos[1];\
						pos[2]=tpos[2];\
						code=c;\
					}\
				}\
			else if(depth##ox<0.f) RETURN0;\
\
}\
}

accurate_normalize(triSideAx0);
if(outV0&&outV1) 
TEST(0,1,2,7)

accurate_normalize(triSideAx1);
if(outV1&&outV2) 
TEST(1,2,0,8)

accurate_normalize(triSideAx2);
if(outV2&&outV0) 
TEST(2,0,1,9)
#undef TEST

////////////////////////////////////
//test cylinder rings on triangle sides////
////////////////////////////////////

dVector3 tAx,cen;
dReal sign;
bool cs;

#define TEST(ax,nx,ox,c)	\
{\
posProj=dDOT(p,triSideAx##ax)-dDOT(v##ax,triSideAx##ax);\
axis[0]=p[0]-v0[0]-triSideAx##ax[0]*posProj;\
axis[1]=p[1]-v0[1]-triSideAx##ax[1]*posProj;\
axis[2]=p[2]-v0[2]-triSideAx##ax[2]*posProj;\
	\
sign=dDOT14(axis,R+1)>0.f ? 1.f :-1.f;\
cen[0]=p[0]-sign*R[1]*hlz;\
cen[1]=p[1]-sign*R[5]*hlz;\
cen[2]=p[2]-sign*R[9]*hlz;\
\
cs=circleLineIntersection(R+1,cen,radius,triSideAx##ax,v##ax,-sign,tpos);\
\
axis[0]=tpos[0]-cen[0];\
axis[1]=tpos[1]-cen[1];\
axis[2]=tpos[2]-cen[2];\
\
if(cs){ \
\
cos0=dDOT14(axis,R+0);\
cos2=dDOT14(axis,R+2);\
tAx[0]=R[2]*cos0-R[0]*cos2;\
tAx[1]=R[6]*cos0-R[4]*cos2;\
tAx[2]=R[10]*cos0-R[8]*cos2;\
\
dCROSS(axis,=,triSideAx##ax,tAx);\
\
}\
accurate_normalize(axis);\
dist##ax=dDOT(v##ax,axis)-dDOT(p,axis);\
if(dist##ax*dDOT(axis,triSideAx##nx)>0.f){\
\
cos0=dDOT14(axis,R+0);\
cos1=dFabs(dDOT14(axis,R+1));\
cos2=dDOT14(axis,R+2);\
\
\
sin1=_sqrt(cos0*cos0+cos2*cos2);\
\
sidePr=cos1*hlz+sin1*radius;\
\
\
	dist##ox=dDOT(v##ox,axis)-dDOT(p,axis);\
\
	isPdist##ax=dist##ax>0.f;\
	isPdist##ox=dist##ox>0.f;\
\
	if(isPdist##ax == isPdist##ox) \
\
{\
depth##ax=sidePr-dFabs(dist##ax);\
depth##ox=sidePr-dFabs(dist##ox);\
	\
			if(depth##ax>0.f){\
				if(depth##ax<outDepth) \
					{\
						outDepth=depth##ax;\
						signum= isPdist##ax ? 1.f : -1.f;\
						outAx[0]=axis[0];\
						outAx[1]=axis[1];\
						outAx[2]=axis[2];\
						pos[0]=tpos[0];\
						pos[1]=tpos[1];\
						pos[2]=tpos[2];\
						code=c;\
					}\
				}\
			else if(depth##ox<0.f) RETURN0;\
\
\
}\
}\
}

if(7!=code)
	TEST(0,1,2,10)

if(8!=code)
	TEST(1,2,0,11)

if(9!=code)
	TEST(2,0,1,12)

#undef TEST

//}
//////////////////////////////////////////////////////////////////////
///if we get to this poit tri touches cylinder///////////////////////
/////////////////////////////////////////////////////////////////////
//VERIFY( g_pGameLevel );
CDB::TRI*       T_array      = inl_ph_world().ObjectSpace().GetStaticTris();
dVector3 norm;
unsigned int ret;
flags8& gl_state=gl_cl_tries_state[I-B];
if(code==0){
	norm[0]=triAx[0]*signum;
	norm[1]=triAx[1]*signum;
	norm[2]=triAx[2]*signum;


  dReal Q1 = dDOT14(norm,R+0);
  dReal Q2 = dDOT14(norm,R+1);
  dReal Q3 = dDOT14(norm,R+2);
  dReal factor =_sqrt(Q1*Q1+Q3*Q3);
  dReal	C1,C3;
  dReal centerDepth;//depth in the cirle centre
  if(factor>0.f)
  {
  		C1=Q1/factor;
		C3=Q3/factor;
		
  }
  else
  {
		C1=1.f;
		C3=0.f;
	
  }
  
  dReal A1 = radius *		C1;//cosinus
  dReal A2 = hlz;//Q2
  dReal A3 = radius *		C3;//sinus 
	
  if(factor>0.f) centerDepth=outDepth-A1*Q1-A3*Q3; else centerDepth=outDepth;

  pos[0]=p[0];
  pos[1]=p[1];
  pos[2]=p[2];
 
  pos[0]+= Q2>0 ? hlz*R[1]:-hlz*R[1];
  pos[1]+= Q2>0 ? hlz*R[5]:-hlz*R[5];
  pos[2]+= Q2>0 ? hlz*R[9]:-hlz*R[9];

  
  
  
  ret=0;
  dVector3 cross0, cross1, cross2;
  dReal ds0,ds1,ds2;
  
  dCROSS(cross0,=,triAx,triSideAx0);
  ds0=dDOT(cross0,v0);

  dCROSS(cross1,=,triAx,triSideAx1);
  ds1=dDOT(cross1,v1);

  dCROSS(cross2,=,triAx,triSideAx2);
  ds2=dDOT(cross2,v2);

  contact->pos[0] = pos[0]+A1*R[0]+A3*R[2];
  contact->pos[1] = pos[1]+A1*R[4]+A3*R[6];
  contact->pos[2] = pos[2]+A1*R[8]+A3*R[10];

  if(dDOT(cross0,contact->pos)-ds0>0.f && 
	 dDOT(cross1,contact->pos)-ds1>0.f && 
	 dDOT(cross2,contact->pos)-ds2>0.f){
							   contact->depth = outDepth;
							   ret=1;
  }

if(dFabs(Q2)>M_SQRT1_2){

  A1=(-C1*M_COS_PI_3-C3*M_SIN_PI_3)*radius;
  A3=(-C3*M_COS_PI_3+C1*M_SIN_PI_3)*radius;
  CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2];
  CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6];
  CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10];
  CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3;

  if(CONTACT(contact,ret*skip)->depth>0.f)
    if(dDOT(cross0,CONTACT(contact,ret*skip)->pos)-ds0>0.f && 
	   dDOT(cross1,CONTACT(contact,ret*skip)->pos)-ds1>0.f && 
	   dDOT(cross2,CONTACT(contact,ret*skip)->pos)-ds2>0.f) ++ret;
  
  A1=(-C1*M_COS_PI_3+C3*M_SIN_PI_3)*radius;
  A3=(-C3*M_COS_PI_3-C1*M_SIN_PI_3)*radius;
  CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2];
  CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6];
  CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10];
  CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3;

  if(CONTACT(contact,ret*skip)->depth>0.f)
    if(dDOT(cross0,CONTACT(contact,ret*skip)->pos)-ds0>0.f && 
	   dDOT(cross1,CONTACT(contact,ret*skip)->pos)-ds1>0.f && 
	   dDOT(cross2,CONTACT(contact,ret*skip)->pos)-ds2>0.f) ++ret;
} else {

  CONTACT(contact,ret*skip)->pos[0]=contact->pos[0]-2.f*(Q2>0 ? hlz*R[1]:-hlz*R[1]);
  CONTACT(contact,ret*skip)->pos[1]=contact->pos[1]-2.f*(Q2>0 ? hlz*R[5]:-hlz*R[5]);
  CONTACT(contact,ret*skip)->pos[2]=contact->pos[2]-2.f*(Q2>0 ? hlz*R[9]:-hlz*R[9]);
  CONTACT(contact,ret*skip)->depth=outDepth-dFabs(Q2*2.f*A2);

  if(CONTACT(contact,ret*skip)->depth>0.f)
    if(dDOT(cross0,CONTACT(contact,ret*skip)->pos)-ds0>0.f && 
	   dDOT(cross1,CONTACT(contact,ret*skip)->pos)-ds1>0.f && 
	   dDOT(cross2,CONTACT(contact,ret*skip)->pos)-ds2>0.f) ++ret;
}
	}
Esempio n. 12
0
void PS::CPEDef::CollisionCutoffOnBeforeEdit(PropValue* sender, float& edit_val)
{    edit_val = _sqrt(edit_val);}
Esempio n. 13
0
float CCar::GravityFactorImpulse()
{
	return _sqrt(EffectiveGravity()/physics_world()->Gravity());
}
Esempio n. 14
0
ISTBOOL GetSphereFrom4Points(struct sphere_model *model)
{
	ISTFLOAT a[4][4] = {{0}};
	ISTFLOAT ho[3] = {0};
	ISTFLOAT norm = 0;
	ISTFLOAT rad = 0;
	ISTFLOAT tmpf = 0;
	ISTFLOAT two = _float(2);
	ISTFLOAT m11, m12, m13, m14, m15;
	ISTINT i, j;

	// Get sphere from 4 points
	for (i = 0; i < 4; i++) { /* find minor 11 */
		a[i][0] = model->p4s[i][0];
		a[i][1] = model->p4s[i][1];
		a[i][2] = model->p4s[i][2];
		a[i][3] = _one;
	}
	m11 = GetDet(a, 4);
	for (i = 0; i < 4; i++) { /* find minor 12 */
		a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]),
			_mul(model->p4s[i][1], model->p4s[i][1])),
			_mul(model->p4s[i][2], model->p4s[i][2]));
		a[i][1] = model->p4s[i][1];
		a[i][2] = model->p4s[i][2];
		a[i][3] = _one;
	}
	m12 = GetDet(a, 4);
	for (i = 0; i < 4; i++) { /* find minor 13 */
		a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]),
			_mul(model->p4s[i][1], model->p4s[i][1])),
			_mul(model->p4s[i][2], model->p4s[i][2]));
		a[i][1] = model->p4s[i][0];
		a[i][2] = model->p4s[i][2];
		a[i][3] = _one;
	}
	m13 = GetDet(a, 4);
	for (i = 0; i < 4; i++) { /* find minor 14 */
		a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]),
			_mul(model->p4s[i][1], model->p4s[i][1])),
			_mul(model->p4s[i][2], model->p4s[i][2]));
		a[i][1] = model->p4s[i][0];
		a[i][2] = model->p4s[i][1];
		a[i][3] = _one;
	}
	m14 = GetDet(a, 4);
	for (i = 0; i < 4; i++) { /* find minor 15 */
		a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]),
			_mul(model->p4s[i][1], model->p4s[i][1])),
			_mul(model->p4s[i][2], model->p4s[i][2]));
		a[i][1] = model->p4s[i][0];
		a[i][2] = model->p4s[i][1];
		a[i][3] = model->p4s[i][2];
	}
	m15 = GetDet(a, 4);
	if (_eq(m11, 0)) {
		rad = 0;
	} else { /* center of sphere */
		ho[0] = _div(_div(m12, m11), two);
		ho[1] = _neg(_div(_div(m13, m11), two));
		ho[2] = _div(_div(m14, m11), two);
		norm = _sub(_add(_add(_mul(ho[0], ho[0]),
			_mul(ho[1], ho[1])),
			_mul(ho[2], ho[2])),
			_div(m15, m11));
		if (_ge(norm, 0)) {
			rad = _sqrt(norm);
		}
	}
	if (_le(rad, 0)) {
		goto EXIT;
	}
	// Check distance
	for (i = 0; i < 4; i++) {
		for (j = (i + 1); j < 4; j++) {
			tmpf = GetDistance(model->p4s[i], model->p4s[j]);
			if (_lt(tmpf, rad) || _lt(tmpf, model->rad_min)) {
				goto EXIT;
			}
		}
	}
	// Update offset 
	for (i = 1; i < IST_SPHERE_OFFSET_NUM; i++) {
		for (j = 0; j < 3; ++j) {
			model->offsets[IST_SPHERE_OFFSET_NUM - i][j] = model->offsets[IST_SPHERE_OFFSET_NUM - i - 1][j];
		}
	}
	for (j = 0; j < 3; ++j) {
		model->offsets[0][j] = ho[j];
	}
	for (i = (IST_SPHERE_DATAMAX >> 1); i < IST_SPHERE_DATAMAX; i++) {
		for (j = 0; j < 3; ++j) {
			model->data[i][j] = _max;
		}
	}
	// Check offset buffer full
	if (IsInitedVector(model->offsets[IST_SPHERE_OFFSET_NUM - 1])) {
		goto EXIT;
	}
	// Calculate mean bias and radius
	if (!GetParams(model, rad)) {
		goto EXIT;
	}
	return ISTTRUE;

EXIT:
	return ISTFALSE;
}
Esempio n. 15
0
void CLevelGraph::draw_objects		(const int &vertex_id)
{
	if (!ai().get_alife())
		return;

	const float					radius = .0105f;
	const u32					color = D3DCOLOR_XRGB(255,0,0);
	const CGameGraph			&graph = ai().game_graph();
	CGameFont					&font = *HUD().Font().pFontDI;
	Fvector						position = convert_position(graph.vertex(vertex_id)->game_point());

	font.SetColor				(D3DCOLOR_XRGB(255,255,0));

	bool						show_text = true;
	for (;;) {
		Fvector4				temp;
		Device.mFullTransform.transform (temp,position);
		font.OutSetI			(temp.x,-temp.y);
		font.SetHeightI			(.05f/_sqrt(temp.w));
		
		if (temp.z < 0.f) {
			show_text			= false;
			break;
		}

		if (temp.w < 0.f) {
			show_text			= false;
			break;
		}

		if (temp.x < -1.f) {
			show_text			= false;
			break;
		}
		
		if (temp.x > 1.f) {
			show_text			= false;
			break;
		}

		if (temp.y < -1.f) {
			show_text			= false;
			break;
		}
		
		if (temp.x > 1.f) {
			show_text			= false;
			break;
		}

		break;
	}

	typedef CALifeGraphRegistry::OBJECT_REGISTRY	OBJECT_REGISTRY;
	typedef OBJECT_REGISTRY::_const_iterator		const_iterator;
	typedef CALifeMonsterDetailPathManager::PATH	PATH;
	const OBJECT_REGISTRY		&objects = ai().alife().graph().objects()[vertex_id].objects();

	CDebugRenderer				&render = Level().debug_renderer();
	if (show_text) {
		bool					first_time = true;
		const_iterator			I = objects.objects().begin();
		const_iterator			E = objects.objects().end();
		for (; I != E; ++I) {
			CSE_ALifeDynamicObject	*object = (*I).second;
			CSE_ALifeMonsterAbstract*monster = smart_cast<CSE_ALifeMonsterAbstract*>(object);
			if (!monster)
				continue;

			const PATH			&path = monster->brain().movement().detail().path();
			const float			&walked_distance = (path.size() < 2) ? 0.f : monster->brain().movement().detail().walked_distance();
//			font.OutNext		("%s",monster->name_replace());

			if ((path.size() >= 2) && !fis_zero(walked_distance))
				continue;

			if (!first_time)
				continue;

			Fvector				position = convert_position(graph.vertex(monster->m_tGraphID)->game_point());
			render.draw_aabb	(position,radius,radius,radius,color);
			first_time			= false;
			continue;
		}
	}

	const_iterator				I = objects.objects().begin();
	const_iterator				E = objects.objects().end();
	for (; I != E; ++I) {
		CSE_ALifeDynamicObject	*object = (*I).second;
		CSE_ALifeMonsterAbstract*monster = smart_cast<CSE_ALifeMonsterAbstract*>(object);
		if (!monster)
			continue;

		const PATH				&path = monster->brain().movement().detail().path();
		if (path.size() < 2)
			continue;

		u32						game_vertex_id0 = monster->m_tGraphID;
		u32						game_vertex_id1 = path[path.size() - 2];
		const float				&walked_distance = monster->brain().movement().detail().walked_distance();

		if (fis_zero(walked_distance))
			continue;

		Fvector					position0 = graph.vertex(game_vertex_id0)->game_point();
		Fvector					position1 = graph.vertex(game_vertex_id1)->game_point();
		const float				distance = position0.distance_to(position1);

		position0				= convert_position(position0);
		position1				= convert_position(position1);

		Fvector					direction = Fvector().sub(position1,position0);
		float					magnitude = direction.magnitude();
		direction.normalize		();
		direction.mul			(magnitude*walked_distance/distance);
		direction.add			(position0);
		render.draw_aabb		(direction,radius,radius,radius,color);

		Fvector4				temp;
		Device.mFullTransform.transform (temp,direction);
		
		if (temp.z < 0.f)
			continue;

		if (temp.w < 0.f)
			continue;

		if (temp.x < -1.f)
			continue;
		
		if (temp.x > 1.f)
			continue;

		if (temp.y < -1.f)
			continue;
		
		if (temp.x > 1.f)
			continue;

		font.SetHeightI			(.05f/_sqrt(temp.w));
	}
}
Esempio n. 16
0
float CExplosive::ExplosionEffect(collide::rq_results& storage, CExplosive*exp_obj,CPhysicsShellHolder*blasted_obj,  const Fvector &expl_centre, const float expl_radius) 
{
	
	const Fmatrix	&obj_xform=blasted_obj->XFORM();
	Fmatrix	inv_obj_form;inv_obj_form.invert(obj_xform);
	Fvector	local_exp_center;inv_obj_form.transform_tiny(local_exp_center,expl_centre);

	const Fbox &l_b1 = blasted_obj->BoundingBox();
	if(l_b1.contains(local_exp_center)) 
										return 1.f;
	Fvector l_c, l_d;l_b1.get_CD(l_c,l_d);
	float effective_volume=l_d.x*l_d.y*l_d.z;
	float max_s=effective_volume/(_min(_min(l_d.x,l_d.y),l_d.z));
	if(blasted_obj->PPhysicsShell()&&blasted_obj->PPhysicsShell()->isActive())
	{
		float ph_volume=blasted_obj->PPhysicsShell()->getVolume();
		if(ph_volume<effective_volume)effective_volume=ph_volume;
	}
	float effect=0.f;
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		Fmatrix dbg_box_m;dbg_box_m.set(obj_xform);
		dbg_box_m.c.set(l_c);obj_xform.transform(dbg_box_m.c);
		DBG_DrawOBB(dbg_box_m,l_d,D3DCOLOR_XRGB(255,255,0));
	}
#endif

	for(u16 i=0;i<TEST_RAYS_PER_OBJECT;++i){
		Fvector l_source_p,l_end_p;
		l_end_p.random_point(l_d);
		l_end_p.add(l_c);
		obj_xform.transform_tiny(l_end_p);
		GetRaySourcePos(exp_obj,expl_centre,l_source_p);
		Fvector l_local_source_p;inv_obj_form.transform_tiny(l_local_source_p,l_source_p);
		if(l_b1.contains(l_local_source_p))
		{
			effect+=1.f;continue;
		}
		Fvector l_dir; l_dir.sub(l_end_p,l_source_p);
		float mag=l_dir.magnitude();
		
		if(fis_zero(mag)) return 1.f;

		l_dir.mul(1.f/mag);
#ifdef DEBUG
			if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
			{
			DBG_DrawPoint(l_source_p,0.1f,D3DCOLOR_XRGB(0,0,255));
			DBG_DrawPoint(l_end_p,0.1f,D3DCOLOR_XRGB(0,0,255));
			DBG_DrawLine(l_source_p,l_end_p,D3DCOLOR_XRGB(0,0,255));
			}
#endif
		
#ifdef DEBUG
		float l_S=effective_volume*(_abs(l_dir.dotproduct(obj_xform.i))/l_d.x+_abs(l_dir.dotproduct(obj_xform.j))/l_d.y+_abs(l_dir.dotproduct(obj_xform.k))/l_d.z);
		float add_eff=_sqrt(l_S/max_s)*TestPassEffect(l_source_p,l_dir,mag,expl_radius,storage,blasted_obj);
		effect+=add_eff;
		if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
		{
			Msg("dist %f,effect R %f",mag,expl_radius);
			Msg("test pass effect %f",add_eff);
			Msg("S effect %f",_sqrt(l_S/max_s));
			Msg("dist/overlap effect, %f",add_eff/_sqrt(l_S/max_s));
		}
#else
		float l_S=effective_volume*(_abs(l_dir.dotproduct(obj_xform.i))/l_d.x+_abs(l_dir.dotproduct(obj_xform.j))/l_d.y+_abs(l_dir.dotproduct(obj_xform.k))/l_d.z);
		effect+=_sqrt(l_S/max_s)*TestPassEffect(l_source_p,l_dir,mag,expl_radius,storage,blasted_obj);
#endif

	}
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
			Msg("damage effect %f",effect/TEST_RAYS_PER_OBJECT);
	}
#endif
	return effect/TEST_RAYS_PER_OBJECT;
	
}
Esempio n. 17
0
mat3& tangent_basis(mat3& basis, const vec3& v0, const vec3& v1, const vec3& v2, const vec2& t0, const vec2& t1, const vec2& t2, const vec3 & n)
{
    vec3 cp;
    vec3 e0(v1.x - v0.x, t1.s - t0.s, t1.t - t0.t);
    vec3 e1(v2.x - v0.x, t2.s - t0.s, t2.t - t0.t);

    cross(cp,e0,e1);
    if ( _abs(cp.x) > nv_eps)
    {
        basis.a00 = -cp.y / cp.x;        
        basis.a10 = -cp.z / cp.x;
    }

    e0.x = v1.y - v0.y;
    e1.x = v2.y - v0.y;

    cross(cp,e0,e1);
    if ( _abs(cp.x) > nv_eps)
    {
        basis.a01 = -cp.y / cp.x;        
        basis.a11 = -cp.z / cp.x;
    }

    e0.x = v1.z - v0.z;
    e1.x = v2.z - v0.z;

    cross(cp,e0,e1);
    if ( _abs(cp.x) > nv_eps)
    {
        basis.a02 = -cp.y / cp.x;        
        basis.a12 = -cp.z / cp.x;
    }

    // tangent...
    nv_scalar oonorm = nv_one / _sqrt(basis.a00 * basis.a00 + basis.a01 * basis.a01 + basis.a02 * basis.a02);
    basis.a00 *= oonorm;
    basis.a01 *= oonorm;
    basis.a02 *= oonorm;

    // binormal...
    oonorm = nv_one / _sqrt(basis.a10 * basis.a10 + basis.a11 * basis.a11 + basis.a12 * basis.a12);
    basis.a10 *= oonorm;
    basis.a11 *= oonorm;
    basis.a12 *= oonorm;

    // normal...
    // compute the cross product TxB
    basis.a20 = basis.a01*basis.a12 - basis.a02*basis.a11;
    basis.a21 = basis.a02*basis.a10 - basis.a00*basis.a12;
    basis.a22 = basis.a00*basis.a11 - basis.a01*basis.a10;

    oonorm = nv_one / _sqrt(basis.a20 * basis.a20 + basis.a21 * basis.a21 + basis.a22 * basis.a22);
    basis.a20 *= oonorm;
    basis.a21 *= oonorm;
    basis.a22 *= oonorm;

    // Gram-Schmidt orthogonalization process for B
    // compute the cross product B=NxT to obtain 
    // an orthogonal basis
    basis.a10 = basis.a21*basis.a02 - basis.a22*basis.a01;
    basis.a11 = basis.a22*basis.a00 - basis.a20*basis.a02;
    basis.a12 = basis.a20*basis.a01 - basis.a21*basis.a00;

    if (basis.a20 * n.x + basis.a21 * n.y + basis.a22 * n.z < nv_zero)
    {
        basis.a20 = -basis.a20;
        basis.a21 = -basis.a21;
        basis.a22 = -basis.a22;
    }
    return basis;
}
Esempio n. 18
0
void CGlowManager::render_selected()
{
	// 2. Sort by shader
	std::sort		(Selected.begin(),Selected.end(),glow_compare);

	FVF::LIT		*pv;

	u32				pos = 0, count;
	ref_shader		T;

	Fplane			NP;
	NP.build		(Device.vCameraPosition,Device.vCameraDirection);

	float		dlim2	= MAX_GlowsDist2;
	for (;pos<Selected.size();) 
	{
		T		= ((CGlow*)Selected[pos]._get())->shader;
		count	= 0;
		while	((pos+count<Selected.size()) && (((CGlow*)Selected[pos+count]._get())->shader==T)) count++;

		u32		vOffset;
		u32		end		= pos+count;
		FVF::LIT* pvs	= pv = (FVF::LIT*) RCache.Vertex.Lock(count*4,hGeom->vb_stride,vOffset);
		for (; pos<end; pos++)
		{
			// Cull invisible 
			CGlow&	G					= *( (CGlow*)Selected[pos]._get() );
			if (G.fade<=1.f)			continue;

			// Now perform dotproduct if need it
			float	scale	= 1.f, dist_sq;
			Fvector	dir;
			dir.sub			(Device.vCameraPosition,G.position);
			dist_sq			= dir.square_magnitude();
			if (G.direction.square_magnitude()>EPS)	{
				dir.div			(_sqrt(dist_sq));
				scale			= dir.dotproduct(G.direction);
			}
			if (G.fade*scale<=1.f)		continue;

			// near fade
			float dist_np	= NP.distance(G.position)-VIEWPORT_NEAR;
			float snear		= dist_np/0.15f;	clamp	(snear,0.f,1.f);
			scale			*=	snear;
			if (G.fade*scale<=1.f)		continue;

			u32 C			= iFloor(G.fade*scale*(1-(dist_sq/dlim2)));
			u32 clr			= color_rgba(C,C,C,C);
			Fvector	gp		;
					gp.mad	(G.position,dir,G.radius*scale);
			FillSprite		(pv,G.position,G.radius,clr);
		}
		int vCount				= int(pv-pvs);
		RCache.Vertex.Unlock	(vCount,hGeom->vb_stride);
		if (vCount) {
			RCache.set_Shader		(T);
			RCache.set_Geometry		(hGeom);
			RCache.Render			(D3DPT_TRIANGLELIST,vOffset,0,vCount,0,vCount/2);
		}
	}
	Selected.clear_not_free			();
}
Esempio n. 19
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);
		}
}
void CRenderTarget::accum_direct_f		(u32 sub_phase)
{
	// Select target
	if (SE_SUN_LUMINANCE==sub_phase)	{
		accum_direct_lum	();
		return				;
	}
	phase_accumulator					();
	u_setrt								(rt_Generic_0,NULL,NULL,HW.pBaseZB);

	// *** assume accumulator setted up ***
	light*			fuckingsun			= (light*)RImplementation.Lights.sun_adapted._get()	;

	// Common calc for quad-rendering
	u32		Offset;
	u32		C					= color_rgba	(255,255,255,255);
	float	_w					= float			(Device.dwWidth);
	float	_h					= float			(Device.dwHeight);
	Fvector2					p0,p1;
	p0.set						(.5f/_w, .5f/_h);
	p1.set						((_w+.5f)/_w, (_h+.5f)/_h );
	float	d_Z	= EPS_S, d_W = 1.f;

	// Common constants (light-related)
	Fvector		L_dir,L_clr;	float L_spec;
	L_clr.set					(fuckingsun->color.r,fuckingsun->color.g,fuckingsun->color.b);
	L_spec						= u_diffuse2s	(L_clr);
	Device.mView.transform_dir	(L_dir,fuckingsun->direction);
	L_dir.normalize				();

	// Perform masking (only once - on the first/near phase)
	RCache.set_CullMode			(CULL_NONE	);
	if (SE_SUN_NEAR==sub_phase)	//.
	{
		// For sun-filter - clear to zero
		CHK_DX	(HW.pDevice->Clear	( 0L, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0L));

		// Fill vertex buffer
		FVF::TL* pv					= (FVF::TL*)	RCache.Vertex.Lock	(4,g_combine->vb_stride,Offset);
		pv->set						(EPS,			float(_h+EPS),	d_Z,	d_W, C, p0.x, p1.y);	pv++;
		pv->set						(EPS,			EPS,			d_Z,	d_W, C, p0.x, p0.y);	pv++;
		pv->set						(float(_w+EPS),	float(_h+EPS),	d_Z,	d_W, C, p1.x, p1.y);	pv++;
		pv->set						(float(_w+EPS),	EPS,			d_Z,	d_W, C, p1.x, p0.y);	pv++;
		RCache.Vertex.Unlock		(4,g_combine->vb_stride);
		RCache.set_Geometry			(g_combine);

		// setup
		float	intensity			= 0.3f*fuckingsun->color.r + 0.48f*fuckingsun->color.g + 0.22f*fuckingsun->color.b;
		Fvector	dir					= L_dir;
		dir.normalize().mul	(- _sqrt(intensity+EPS));
		RCache.set_Element			(s_accum_mask->E[SE_MASK_DIRECT]);		// masker
		RCache.set_c				("Ldynamic_dir",		dir.x,dir.y,dir.z,0		);

		// if (stencil>=1 && aref_pass)	stencil = light_id
		RCache.set_ColorWriteEnable	(FALSE		);
		RCache.set_Stencil			(TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0x01,0xff,D3DSTENCILOP_KEEP,D3DSTENCILOP_REPLACE,D3DSTENCILOP_KEEP);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
	}

	// recalculate d_Z, to perform depth-clipping
	Fvector	center_pt;			center_pt.mad	(Device.vCameraPosition,Device.vCameraDirection,ps_r2_sun_near);
	Device.mFullTransform.transform(center_pt)	;
	d_Z							= center_pt.z	;

	// nv-stencil recompression
	if (RImplementation.o.nvstencil  && (SE_SUN_NEAR==sub_phase))	u_stencil_optimize();	//. driver bug?

	// Perform lighting
	{
		u_setrt								(rt_Generic_0,NULL,NULL,HW.pBaseZB);  // enshure RT setup
		RCache.set_CullMode					(CULL_NONE	);
		RCache.set_ColorWriteEnable			();

		// texture adjustment matrix
		float			fTexelOffs			= (.5f / float(RImplementation.o.smapsize));
		float			fRange				= (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_scale:ps_r2_sun_depth_far_scale;
		float			fBias				= (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias;
		Fmatrix			m_TexelAdjust		= 
		{
			0.5f,				0.0f,				0.0f,			0.0f,
			0.0f,				-0.5f,				0.0f,			0.0f,
			0.0f,				0.0f,				fRange,			0.0f,
			0.5f + fTexelOffs,	0.5f + fTexelOffs,	fBias,			1.0f
		};

		// compute xforms
		Fmatrix				m_shadow;
		{
			FPU::m64r		();
			Fmatrix			xf_invview;		xf_invview.invert	(Device.mView)	;
			Fmatrix			xf_project;		xf_project.mul		(m_TexelAdjust,fuckingsun->X.D.combine);
			m_shadow.mul	(xf_project,	xf_invview);

			// tsm-bias
			if (SE_SUN_FAR == sub_phase)
			{
				Fvector		bias;	bias.mul		(L_dir,ps_r2_sun_tsm_bias);
				Fmatrix		bias_t;	bias_t.translate(bias);
				m_shadow.mulB_44	(bias_t);
			}
			FPU::m24r		();
		}

		// Make jitter texture
		Fvector2					j0,j1;
		float	scale_X				= float(Device.dwWidth)	/ float(TEX_jitter);
		//float	scale_Y				= float(Device.dwHeight)/ float(TEX_jitter);
		float	offset				= (.5f / float(TEX_jitter));
		j0.set						(offset,offset);
		j1.set						(scale_X,scale_X).add(offset);

		// Fill vertex buffer
		FVF::TL2uv* pv				= (FVF::TL2uv*) RCache.Vertex.Lock	(4,g_combine_2UV->vb_stride,Offset);
		pv->set						(EPS,			float(_h+EPS),	d_Z,	d_W, C, p0.x, p1.y, j0.x, j1.y);	pv++;
		pv->set						(EPS,			EPS,			d_Z,	d_W, C, p0.x, p0.y, j0.x, j0.y);	pv++;
		pv->set						(float(_w+EPS),	float(_h+EPS),	d_Z,	d_W, C, p1.x, p1.y, j1.x, j1.y);	pv++;
		pv->set						(float(_w+EPS),	EPS,			d_Z,	d_W, C, p1.x, p0.y, j1.x, j0.y);	pv++;
		RCache.Vertex.Unlock		(4,g_combine_2UV->vb_stride);
		RCache.set_Geometry			(g_combine_2UV);

		// setup
		RCache.set_Element			(s_accum_direct->E[sub_phase]);
		RCache.set_c				("Ldynamic_dir",		L_dir.x,L_dir.y,L_dir.z,0		);
		RCache.set_c				("Ldynamic_color",		L_clr.x,L_clr.y,L_clr.z,L_spec	);
		RCache.set_c				("m_shadow",			m_shadow						);

		// setup stencil
		RCache.set_Stencil			(TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
	}
}
Esempio n. 21
0
void CPhysicObject::net_Export_PH_Params(NET_Packet& P, SPHNetState& State, mask_num_items&	num_items)
{
	//UI().Font().pFontStat->OutSet(100.0f,100.0f);
	P.w_vec3				(State.force);
	//Msg("Export State.force.y:%4.6f",State.force.y);
	P.w_vec3				(State.torque);
	//UI().Font().pFontStat->OutNext("Export State.torque:%4.6f",State.torque.magnitude());
	P.w_vec3				(State.position);
	//Msg("Export State.position.y:%4.6f",State.position.y);
	//Msg("Export State.enabled:%i",int(State.enabled));

	float					magnitude = _sqrt(State.quaternion.magnitude());
	if (fis_zero(magnitude)) {
		magnitude			= 1;
		State.quaternion.x	= 0.f;
		State.quaternion.y	= 0.f;
		State.quaternion.z	= 1.f;
		State.quaternion.w	= 0.f;
	}
	else {
		/*		float				invert_magnitude = 1.f/magnitude;

		State.quaternion.x	*= invert_magnitude;
		State.quaternion.y	*= invert_magnitude;
		State.quaternion.z	*= invert_magnitude;
		State.quaternion.w	*= invert_magnitude;

		clamp				(State.quaternion.x,-1.f,1.f);
		clamp				(State.quaternion.y,-1.f,1.f);
		clamp				(State.quaternion.z,-1.f,1.f);
		clamp				(State.quaternion.w,-1.f,1.f);*/
	}

	P.w_float			(State.quaternion.x);
	P.w_float			(State.quaternion.y);
	P.w_float			(State.quaternion.z);
	P.w_float			(State.quaternion.w);

	if (!(num_items.mask & CSE_ALifeObjectPhysic::inventory_item_angular_null)) {
		/*	clamp				(State.angular_vel.x,-10.f*PI_MUL_2,10.f*PI_MUL_2);
		clamp				(State.angular_vel.y,-10.f*PI_MUL_2,10.f*PI_MUL_2);
		clamp				(State.angular_vel.z,-10.f*PI_MUL_2,10.f*PI_MUL_2);*/

		P.w_float		(State.angular_vel.x);
		P.w_float		(State.angular_vel.y);
		P.w_float		(State.angular_vel.z);
	}

	if (!(num_items.mask & CSE_ALifeObjectPhysic::inventory_item_linear_null)) {
		/*clamp				(State.linear_vel.x,-32.f,32.f);
		clamp				(State.linear_vel.y,-32.f,32.f);
		clamp				(State.linear_vel.z,-32.f,32.f);*/

		P.w_float		(State.linear_vel.x);
		P.w_float		(State.linear_vel.y);
		P.w_float		(State.linear_vel.z);
		//Msg("Export State.linear_vel.y:%4.6f",State.linear_vel.y);
	}
	else
	{
		//Msg("Export State.linear_vel.y:%4.6f",0.0f);
	}
}
Esempio n. 22
0
void CInventoryItem::net_Export			(NET_Packet& P) 
{	
	if (object().H_Parent() || IsGameTypeSingle()) 
	{
		P.w_u8				(0);
		return;
	}
	CPHSynchronize* pSyncObj				= NULL;
	SPHNetState								State;
	pSyncObj = object().PHGetSyncItem		(0);

	if (pSyncObj && !object().H_Parent()) 
		pSyncObj->get_State					(State);
	else 	
		State.position.set					(object().Position());


	mask_num_items			num_items;
	num_items.mask			= 0;
	u16						temp = bone_count_to_synchronize();

	R_ASSERT				(temp < (u16(1) << 5));
	num_items.num_items		= u8(temp);

	if (State.enabled)									num_items.mask |= CSE_ALifeInventoryItem::inventory_item_state_enabled;
	if (fis_zero(State.angular_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_angular_null;
	if (fis_zero(State.linear_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_linear_null;

	P.w_u8					(num_items.common);

	P.w_vec3				(State.position);

	float					magnitude = _sqrt(State.quaternion.magnitude());
	if (fis_zero(magnitude)) {
		magnitude			= 1;
		State.quaternion.x	= 0.f;
		State.quaternion.y	= 0.f;
		State.quaternion.z	= 1.f;
		State.quaternion.w	= 0.f;
	}
	else {
		float				invert_magnitude = 1.f/magnitude;
		
		State.quaternion.x	*= invert_magnitude;
		State.quaternion.y	*= invert_magnitude;
		State.quaternion.z	*= invert_magnitude;
		State.quaternion.w	*= invert_magnitude;

		clamp				(State.quaternion.x,0.f,1.f);
		clamp				(State.quaternion.y,0.f,1.f);
		clamp				(State.quaternion.z,0.f,1.f);
		clamp				(State.quaternion.w,0.f,1.f);
	}

	P.w_float_q8			(State.quaternion.x,0.f,1.f);
	P.w_float_q8			(State.quaternion.y,0.f,1.f);
	P.w_float_q8			(State.quaternion.z,0.f,1.f);
	P.w_float_q8			(State.quaternion.w,0.f,1.f);

	if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_angular_null)) {
		clamp				(State.angular_vel.x,0.f,10.f*PI_MUL_2);
		clamp				(State.angular_vel.y,0.f,10.f*PI_MUL_2);
		clamp				(State.angular_vel.z,0.f,10.f*PI_MUL_2);

		P.w_float_q8		(State.angular_vel.x,0.f,10.f*PI_MUL_2);
		P.w_float_q8		(State.angular_vel.y,0.f,10.f*PI_MUL_2);
		P.w_float_q8		(State.angular_vel.z,0.f,10.f*PI_MUL_2);
	}

	if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_linear_null)) {
		clamp				(State.linear_vel.x,-32.f,32.f);
		clamp				(State.linear_vel.y,-32.f,32.f);
		clamp				(State.linear_vel.z,-32.f,32.f);

		P.w_float_q8		(State.linear_vel.x,-32.f,32.f);
		P.w_float_q8		(State.linear_vel.y,-32.f,32.f);
		P.w_float_q8		(State.linear_vel.z,-32.f,32.f);
	}
};