コード例 #1
0
ファイル: PHGeometryOwner.cpp プロジェクト: 2asoft/xray
void CPHGeometryOwner::add_Shape(const SBoneShape& shape,const Fmatrix& offset)
{
	switch(shape.type) {
	case SBoneShape::stBox	:
		{
			Fobb box=shape.box;
			Fmatrix m;
			m.set(offset);
			//Fmatrix position;
			//position.set(box.m_rotate);
			//position.c.set(box.m_translate);
			//position.mulA(offset);
			//box.m_rotate.set(position);
			//box.m_translate.set(position.c);
			box.transform(box,m);
			add_Box(box);
			break;
		}
	case SBoneShape::stSphere	:
		{
			Fsphere sphere=shape.sphere;
			offset.transform_tiny(sphere.P);
			add_Sphere(sphere);
			break;
		}


	case SBoneShape::stCylinder :
		{
			Fcylinder C=shape.cylinder;
			offset.transform_tiny(C.m_center);
			offset.transform_dir(C.m_direction);
			add_Cylinder(C);
			break;
		}


	case SBoneShape::stNone :
		break;
	default: NODEFAULT;
	}
}
コード例 #2
0
ファイル: GroupObject.cpp プロジェクト: OLR-xray/OLR-3.0
void CGroupObject::RotateLocal(Fvector& axis, float angle )
{
	inherited::RotateLocal(axis,angle);
    Fmatrix  Ginv;
    Ginv.set		(FITransformRP);
	UpdateTransform	(true);
	for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){
    	Fmatrix 	O,On;
        O.mul		(Ginv,(*it)->FTransformRP);
        On.mul		(FTransform,O);
        Fvector 	xyz;
        On.getXYZ	(xyz);
        (*it)->NumSetRotation(xyz);
        (*it)->NumSetPosition(On.c);
//		(*it)->PivotRotateParent(m_old,FTransform,axis,angle);
    }
/*    
	for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++)
		(*it)->PivotRotateLocal(FTransformRP,FPosition,axis,angle);
*/
}
コード例 #3
0
ファイル: ShootingObject.cpp プロジェクト: 2asoft/xray
void CShootingObject::UpdateFlameParticles	()
{
	if(0==m_sFlameParticlesCurrent.size())		return;
	if(!m_pFlameParticles)				return;

	Fmatrix		pos; 
	pos.set		(get_ParticlesXFORM()	); 
	pos.c.set	(get_CurrentFirePoint()	);

	VERIFY(_valid(pos));

	m_pFlameParticles->SetXFORM			(pos);

	if(!m_pFlameParticles->IsLooped() && 
		!m_pFlameParticles->IsPlaying() &&
		!m_pFlameParticles->PSI_alive())
	{
		m_pFlameParticles->Stop();
		CParticlesObject::Destroy(m_pFlameParticles);
	}
}
コード例 #4
0
ファイル: poltergeist.cpp プロジェクト: 2asoft/xray
void CPoltergeist::Die(CObject* who)
{
	if (m_tele) {
		if (state_invisible) {
			setVisible(true);

			if (PPhysicsShell()) {
				Fmatrix M;
				M.set							(XFORM());
				M.translate_over				(m_current_position);
				PPhysicsShell()->SetTransform	(M);
			} else 
				Position() = m_current_position;
		}
	}

	inherited::Die				(who);
	Energy::disable				();

	ability()->on_die			();
}
コード例 #5
0
void CParticleGroup::SItem::StartFreeChild(CParticleEffect* emitter, LPCSTR nm, PAPI::Particle& m)
{
    CParticleEffect*C			= static_cast<CParticleEffect*>(RImplementation.model_CreatePE(nm));
    if(!C->IsLooped()){
        Fmatrix M; 				M.identity();
        Fvector vel; 			vel.sub(m.pos,m.posB); vel.div(fDT_STEP);
        if (emitter->m_RT_Flags.is(CParticleEffect::flRT_XFORM)){
        	M.set				(emitter->m_XFORM);
            M.transform_dir		(vel);
        };
        Fvector 				p;
        M.transform_tiny		(p,m.pos);
        M.c.set					(p);
        C->Play					();
        C->UpdateParent			(M,vel,FALSE);
        _children_free.push_back(C);
    }else{
#ifdef _EDITOR        
        Msg			("!Can't use looped effect '%s' as 'On Birth' child for group.",nm);
#else
        Debug.fatal	(DEBUG_INFO,"Can't use looped effect '%s' as 'On Birth' child for group.",nm);
#endif
    }
}
コード例 #6
0
ファイル: ParticlesPlayer.cpp プロジェクト: OLR-xray/XRay-NEW
void CParticlesPlayer::StartParticles(const shared_str& ps_name, const Fmatrix& xform, u16 sender_id, int life_time, bool auto_stop)
{

    CObject* object					= m_self_object;
    VERIFY(object);
    for(BoneInfoVecIt it = m_Bones.begin(); it!=m_Bones.end(); it++) {

        SParticlesInfo &particles_info	=*it->AppendParticles(object,ps_name);
        particles_info.sender_id	= sender_id;

        particles_info.life_time=auto_stop ? life_time : u32(-1);
        xform.getHPB(particles_info.angles);
        //начать играть партиклы

        Fmatrix m;
        m.set(xform);
        GetBonePos(object,it->index,it->offset,m.c);
        particles_info.ps->UpdateParent(m,zero_vel);
        if(!particles_info.ps->IsPlaying())
            particles_info.ps->Play	();
    }

    m_bActiveBones = true;
}
コード例 #7
0
ファイル: Weapon.cpp プロジェクト: AntonioModer/xray-16
void CWeapon::UpdateXForm	()
{
	if (Device.dwFrame == dwXF_Frame)
		return;

	dwXF_Frame				= Device.dwFrame;

	if (!H_Parent())
		return;

	// Get access to entity and its visual
	CEntityAlive*			E = smart_cast<CEntityAlive*>(H_Parent());
	
	if (!E) {
		if (!IsGameTypeSingle())
			UpdatePosition	(H_Parent()->XFORM());

		return;
	}

	const CInventoryOwner	*parent = smart_cast<const CInventoryOwner*>(E);
	if (parent && parent->use_simplified_visual())
		return;

	if (parent->attached(this))
		return;

	IKinematics*			V = smart_cast<IKinematics*>	(E->Visual());
	VERIFY					(V);

	// Get matrices
	int						boneL = -1, boneR = -1, boneR2 = -1;

	// this ugly case is possible in case of a CustomMonster, not a Stalker, nor an Actor
	E->g_WeaponBones		(boneL,boneR,boneR2);

	if (boneR == -1)		return;

	if ((HandDependence() == hd1Hand) || (GetState() == eReload) || (!E->g_Alive()))
		boneL				= boneR2;

	V->CalculateBones		();
	Fmatrix& mL				= V->LL_GetTransform(u16(boneL));
	Fmatrix& mR				= V->LL_GetTransform(u16(boneR));
	// Calculate
	Fmatrix					mRes;
	Fvector					R,D,N;
	D.sub					(mL.c,mR.c);	

	if(fis_zero(D.magnitude())) {
		mRes.set			(E->XFORM());
		mRes.c.set			(mR.c);
	}
	else {		
		D.normalize			();
		R.crossproduct		(mR.j,D);

		N.crossproduct		(D,R);			
		N.normalize			();

		mRes.set			(R,N,D,mR.c);
		mRes.mulA_43		(E->XFORM());
	}

	UpdatePosition			(mRes);
}
コード例 #8
0
ファイル: IKLimb.cpp プロジェクト: OLR-xray/XRay-NEW
void CIKLimb::GoalMatrix(Matrix &M,SCalculateData* cd)
{
		VERIFY(cd->m_tri&&cd->m_tri_hight!=-dInfinity);
		const Fmatrix &obj=*cd->m_obj;
		CDB::TRI	*tri=cd->m_tri;
		CKinematics *K=cd->m_K;
		Fvector*	pVerts	= Level().ObjectSpace.GetStaticVerts();
		Fvector normal;
		normal.mknormal	(pVerts[tri->verts[0]],pVerts[tri->verts[1]],pVerts[tri->verts[2]]);
		VERIFY(!fis_zero(normal.magnitude()));

		Fmatrix iobj;iobj.invert(obj);iobj.transform_dir(normal);

		Fmatrix xm;xm.set(K->LL_GetTransform(m_bones[2]));

		//Fvector dbg;
		//dbg.set(Fvector().mul(normal,normal.y*tri_hight
		//	-normal.dotproduct(xm.i)*m_toe_position.x
		//	-normal.dotproduct(xm.j)*m_toe_position.y
		//	-normal.dotproduct(xm.k)*m_toe_position.z-m_toe_position.x
		//	));
		
		normal.invert();
		Fvector ax;ax.crossproduct(normal,xm.i);
		float s=ax.magnitude();
		if(!fis_zero(s))
		{
			ax.mul(1.f/s);

			xm.mulA_43(Fmatrix().rotation(ax,asinf(-s)));
		}

		Fvector otri;iobj.transform_tiny(otri,pVerts[tri->verts[0]]);
		float tp=normal.dotproduct(otri);
		Fvector add;
		add.set(Fvector().mul(normal,-m_toe_position.x+tp-xm.c.dotproduct(normal)));

		xm.c.add(add);
		
	
		Fmatrix H;
		CBoneData& bd=K->LL_GetData(m_bones[0]);
		H.set(bd.bind_transform);
	
		H.mulA_43(K->LL_GetTransform(bd.GetParentID()));
		H.c.set(K->LL_GetTransform(m_bones[0]).c);

	
#ifdef DEBUG
		if(ph_dbg_draw_mask.test(phDbgIKAnimGoalOnly))	xm.set(K->LL_GetTransform(m_bones[2]));
		if(ph_dbg_draw_mask.test(phDbgDrawIKGoal))
		{
			Fmatrix DBGG;
			DBGG.mul_43(obj,xm);
			DBG_DrawMatrix(DBGG,0.2f);

			
			DBGG.mul_43(obj,H);
			DBG_DrawMatrix(DBGG,0.2f);
		}
#endif
		H.invert();
		Fmatrix G; 
		G.mul_43(H,xm);
		XM2IM(G,M);
}
コード例 #9
0
ファイル: SceneObject.cpp プロジェクト: OLR-xray/OLR-3.0
void CSceneObject::GetFullTransformToWorld( Fmatrix& m )
{
    m.set(_Transform());
}
コード例 #10
0
ファイル: SkeletonAnimated.cpp プロジェクト: OLR-xray/OLR-3.0
void	CKinematicsAnimated::Bone_GetAnimPos(Fmatrix& pos,u16 id,u8 mask_channel, bool ignore_callbacks)
{
	CBoneInstance bi = LL_GetBoneInstance(id);
	BoneChain_Calculate(&LL_GetData(id),bi,mask_channel,ignore_callbacks);
	pos.set(bi.mTransform);
}
コード例 #11
0
void	CRenderTarget::phase_combine	()
{
	bool	_menu_pp	= g_pGamePersistent?g_pGamePersistent->OnRenderPPUI_query():false;

	u32			Offset					= 0;
	Fvector2	p0,p1;

	//*** exposure-pipeline
	u32			gpu_id	= Device.dwFrame%2;
	{
		t_LUM_src->surface_set		(rt_LUM_pool[gpu_id*2+0]->pSurface);
		t_LUM_dest->surface_set		(rt_LUM_pool[gpu_id*2+1]->pSurface);
	}

	// low/hi RTs
	u_setrt				( rt_Generic_0,rt_Generic_1,0,HW.pBaseZB );
	RCache.set_CullMode	( CULL_NONE );
	RCache.set_Stencil	( FALSE		);

	BOOL	split_the_scene_to_minimize_wait			= FALSE;
	if (ps_r2_ls_flags.test(R2FLAG_EXP_SPLIT_SCENE))	split_the_scene_to_minimize_wait=TRUE;

	// draw skybox
	if (1)
	{
		RCache.set_ColorWriteEnable					();
		CHK_DX(HW.pDevice->SetRenderState			( D3DRS_ZENABLE,	FALSE				));
		g_pGamePersistent->Environment().RenderSky	();
		CHK_DX(HW.pDevice->SetRenderState			( D3DRS_ZENABLE,	TRUE				));
	}

	// 
	//if (RImplementation.o.bug)	{
		RCache.set_Stencil					(TRUE,D3DCMP_LESSEQUAL,0x01,0xff,0x00);	// stencil should be >= 1
		if (RImplementation.o.nvstencil)	{
			u_stencil_optimize				(FALSE);
			RCache.set_ColorWriteEnable		();
		}
	//}

	// calc m-blur matrices
	Fmatrix		m_previous, m_current;
	Fvector2	m_blur_scale;
	{
		static Fmatrix		m_saved_viewproj;
		
		// (new-camera) -> (world) -> (old_viewproj)
		Fmatrix	m_invview;	m_invview.invert	(Device.mView);
		m_previous.mul		(m_saved_viewproj,m_invview);
		m_current.set		(Device.mProject)		;
		m_saved_viewproj.set(Device.mFullTransform)	;
		float	scale		= ps_r2_mblur/2.f;
		m_blur_scale.set	(scale,-scale).div(12.f);
	}

	// Draw full-screen quad textured with our scene image
	if (!_menu_pp)
	{
		// Compute params
		Fmatrix		m_v2w;			m_v2w.invert				(Device.mView		);
		CEnvDescriptorMixer& envdesc= g_pGamePersistent->Environment().CurrentEnv		;
		const float minamb			= 0.001f;
		Fvector4	ambclr			= { _max(envdesc.ambient.x*2,minamb),	_max(envdesc.ambient.y*2,minamb),			_max(envdesc.ambient.z*2,minamb),	0	};
					ambclr.mul		(ps_r2_sun_lumscale_amb);
		Fvector4	envclr			= { envdesc.sky_color.x*2+EPS,	envdesc.sky_color.y*2+EPS,	envdesc.sky_color.z*2+EPS,	envdesc.weight					};
		Fvector4	fogclr			= { envdesc.fog_color.x,	envdesc.fog_color.y,	envdesc.fog_color.z,		0	};
					envclr.x		*= 2*ps_r2_sun_lumscale_hemi; 
					envclr.y		*= 2*ps_r2_sun_lumscale_hemi; 
					envclr.z		*= 2*ps_r2_sun_lumscale_hemi;
		Fvector4	sunclr,sundir;

		// sun-params
		{
			light*		fuckingsun		= (light*)RImplementation.Lights.sun_adapted._get()	;
			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				();

			sunclr.set				(L_clr.x,L_clr.y,L_clr.z,L_spec);
			sundir.set				(L_dir.x,L_dir.y,L_dir.z,0);
		}

		// Fill VB
		float	_w					= float(Device.dwWidth);
		float	_h					= float(Device.dwHeight);
		p0.set						(.5f/_w, .5f/_h);
		p1.set						((_w+.5f)/_w, (_h+.5f)/_h );

		// Fill vertex buffer
		Fvector4* pv				= (Fvector4*)	RCache.Vertex.Lock	(4,g_combine_VP->vb_stride,Offset);
		pv->set						(hclip(EPS,		_w),	hclip(_h+EPS,	_h),	p0.x, p1.y);	pv++;
		pv->set						(hclip(EPS,		_w),	hclip(EPS,		_h),	p0.x, p0.y);	pv++;
		pv->set						(hclip(_w+EPS,	_w),	hclip(_h+EPS,	_h),	p1.x, p1.y);	pv++;
		pv->set						(hclip(_w+EPS,	_w),	hclip(EPS,		_h),	p1.x, p0.y);	pv++;
		RCache.Vertex.Unlock		(4,g_combine_VP->vb_stride);

		// Setup textures
		IDirect3DBaseTexture9*	e0	= _menu_pp?0:envdesc.sky_r_textures_env[0].second->surface_get();
		IDirect3DBaseTexture9*	e1	= _menu_pp?0:envdesc.sky_r_textures_env[1].second->surface_get();
		t_envmap_0->surface_set		(e0);	_RELEASE(e0);
		t_envmap_1->surface_set		(e1);	_RELEASE(e1);
	
		// Draw
		RCache.set_Element			(s_combine->E[0]	);
		RCache.set_Geometry			(g_combine_VP		);

		RCache.set_c				("m_v2w",			m_v2w	);
		RCache.set_c				("L_ambient",		ambclr	);

		RCache.set_c				("Ldynamic_color",	sunclr	);
		RCache.set_c				("Ldynamic_dir",	sundir	);

		RCache.set_c				("env_color",		envclr	);
		RCache.set_c				("fog_color",		fogclr	);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
	}

	// Forward rendering
	{
		u_setrt							(rt_Generic_0,0,0,HW.pBaseZB);		// LDR RT
		RCache.set_CullMode				(CULL_CCW);
		RCache.set_Stencil				(FALSE);
		RCache.set_ColorWriteEnable		();
		g_pGamePersistent->Environment().RenderClouds	();
		RImplementation.render_forward	();
		if (g_pGamePersistent)	g_pGamePersistent->OnRenderPPUI_main()	;	// PP-UI
	}

	// Perform blooming filter and distortion if needed
	RCache.set_Stencil	(FALSE);
	phase_bloom			( );												// HDR RT invalidated here

	// Distortion filter
	BOOL	bDistort	= RImplementation.o.distortion_enabled;				// This can be modified
	{
		if		((0==RImplementation.mapDistort.size()) && !_menu_pp)		bDistort= FALSE;
		if (bDistort)		{
			u_setrt						(rt_Generic_1,0,0,HW.pBaseZB);		// Now RT is a distortion mask
			RCache.set_CullMode			(CULL_CCW);
			RCache.set_Stencil			(FALSE);
			RCache.set_ColorWriteEnable	();
			CHK_DX(HW.pDevice->Clear	( 0L, NULL, D3DCLEAR_TARGET, color_rgba(127,127,0,127), 1.0f, 0L));
			RImplementation.r_dsgraph_render_distort	();
			if (g_pGamePersistent)	g_pGamePersistent->OnRenderPPUI_PP()	;	// PP-UI
		}
	}

	// PP enabled ?
	BOOL	PP_Complex		= u_need_PP	();
	if (_menu_pp)			PP_Complex	= FALSE;

	// Combine everything + perform AA
	if		(PP_Complex)	u_setrt		( rt_Color,0,0,HW.pBaseZB );			// LDR RT
	else					u_setrt		( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB);
	//. u_setrt				( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB);
	RCache.set_CullMode		( CULL_NONE )	;
	RCache.set_Stencil		( FALSE		)	;
	if (1)	
	{
		// 
		struct v_aa	{
			Fvector4	p;
			Fvector2	uv0;
			Fvector2	uv1;
			Fvector2	uv2;
			Fvector2	uv3;
			Fvector2	uv4;
			Fvector4	uv5;
			Fvector4	uv6;
		};

		float	_w					= float(Device.dwWidth);
		float	_h					= float(Device.dwHeight);
		float	ddw					= 1.f/_w;
		float	ddh					= 1.f/_h;
		p0.set						(.5f/_w, .5f/_h);
		p1.set						((_w+.5f)/_w, (_h+.5f)/_h );

		// Fill vertex buffer
		v_aa* pv					= (v_aa*) RCache.Vertex.Lock	(4,g_aa_AA->vb_stride,Offset);
		pv->p.set(EPS,			float(_h+EPS),	EPS,1.f); pv->uv0.set(p0.x, p1.y);pv->uv1.set(p0.x-ddw,p1.y-ddh);pv->uv2.set(p0.x+ddw,p1.y+ddh);pv->uv3.set(p0.x+ddw,p1.y-ddh);pv->uv4.set(p0.x-ddw,p1.y+ddh);pv->uv5.set(p0.x-ddw,p1.y,p1.y,p0.x+ddw);pv->uv6.set(p0.x,p1.y-ddh,p1.y+ddh,p0.x);pv++;
		pv->p.set(EPS,			EPS,			EPS,1.f); pv->uv0.set(p0.x, p0.y);pv->uv1.set(p0.x-ddw,p0.y-ddh);pv->uv2.set(p0.x+ddw,p0.y+ddh);pv->uv3.set(p0.x+ddw,p0.y-ddh);pv->uv4.set(p0.x-ddw,p0.y+ddh);pv->uv5.set(p0.x-ddw,p0.y,p0.y,p0.x+ddw);pv->uv6.set(p0.x,p0.y-ddh,p0.y+ddh,p0.x);pv++;
		pv->p.set(float(_w+EPS),float(_h+EPS),	EPS,1.f); pv->uv0.set(p1.x, p1.y);pv->uv1.set(p1.x-ddw,p1.y-ddh);pv->uv2.set(p1.x+ddw,p1.y+ddh);pv->uv3.set(p1.x+ddw,p1.y-ddh);pv->uv4.set(p1.x-ddw,p1.y+ddh);pv->uv5.set(p1.x-ddw,p1.y,p1.y,p1.x+ddw);pv->uv6.set(p1.x,p1.y-ddh,p1.y+ddh,p1.x);pv++;
		pv->p.set(float(_w+EPS),EPS,			EPS,1.f); pv->uv0.set(p1.x, p0.y);pv->uv1.set(p1.x-ddw,p0.y-ddh);pv->uv2.set(p1.x+ddw,p0.y+ddh);pv->uv3.set(p1.x+ddw,p0.y-ddh);pv->uv4.set(p1.x-ddw,p0.y+ddh);pv->uv5.set(p1.x-ddw,p0.y,p0.y,p1.x+ddw);pv->uv6.set(p1.x,p0.y-ddh,p0.y+ddh,p1.x);pv++;
		RCache.Vertex.Unlock		(4,g_aa_AA->vb_stride);

		// Draw COLOR
		if (ps_r2_ls_flags.test(R2FLAG_AA))			RCache.set_Element	(s_combine->E[bDistort?3:1]);	// look at blender_combine.cpp
		else										RCache.set_Element	(s_combine->E[bDistort?4:2]);	// look at blender_combine.cpp
		RCache.set_c				("e_barrier",	ps_r2_aa_barier.x,	ps_r2_aa_barier.y,	ps_r2_aa_barier.z,	0);
		RCache.set_c				("e_weights",	ps_r2_aa_weight.x,	ps_r2_aa_weight.y,	ps_r2_aa_weight.z,	0);
		RCache.set_c				("e_kernel",	ps_r2_aa_kernel,	ps_r2_aa_kernel,	ps_r2_aa_kernel,	0);
		RCache.set_c				("m_current",	m_current);
		RCache.set_c				("m_previous",	m_previous);
		RCache.set_c				("m_blur",		m_blur_scale.x,m_blur_scale.y, 0,0);
		RCache.set_Geometry			(g_aa_AA);
		RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
	}
	RCache.set_Stencil		(FALSE);

	//	if FP16-BLEND !not! supported - draw flares here, overwise they are already in the bloom target
	/* if (!RImplementation.o.fp16_blend)*/	g_pGamePersistent->Environment().RenderFlares	();	// lens-flares

	//	PP-if required
	if (PP_Complex)		{
		phase_pp		();
	}

	//	Re-adapt luminance
	RCache.set_Stencil		(FALSE);

	//*** exposure-pipeline-clear
	{
		std::swap					(rt_LUM_pool[gpu_id*2+0],rt_LUM_pool[gpu_id*2+1]);
		t_LUM_src->surface_set		(NULL);
		t_LUM_dest->surface_set		(NULL);
	}

#ifdef DEBUG
	RCache.set_CullMode	( CULL_CCW );
	static	xr_vector<Fplane>		saved_dbg_planes;
	if (bDebug)		saved_dbg_planes= dbg_planes;
	else			dbg_planes		= saved_dbg_planes;
	if (1) for (u32 it=0; it<dbg_planes.size(); it++)
	{
		Fplane&		P	=	dbg_planes[it];
		Fvector		zero	;
		zero.mul	(P.n,P.d);
		
		Fvector             L_dir,L_up=P.n,L_right;
		L_dir.set           (0,0,1);                if (_abs(L_up.dotproduct(L_dir))>.99f)  L_dir.set(1,0,0);
		L_right.crossproduct(L_up,L_dir);           L_right.normalize       ();
		L_dir.crossproduct  (L_right,L_up);         L_dir.normalize         ();

		Fvector				p0,p1,p2,p3;
		float				sz	= 100.f;
		p0.mad				(zero,L_right,sz).mad	(L_dir,sz);
		p1.mad				(zero,L_right,sz).mad	(L_dir,-sz);
		p2.mad				(zero,L_right,-sz).mad	(L_dir,-sz);
		p3.mad				(zero,L_right,-sz).mad	(L_dir,+sz);
		RCache.dbg_DrawTRI	(Fidentity,p0,p1,p2,0xffffffff);
		RCache.dbg_DrawTRI	(Fidentity,p2,p3,p0,0xffffffff);
	}

	static	xr_vector<dbg_line_t>	saved_dbg_lines;
	if (bDebug)		saved_dbg_lines	= dbg_lines;
	else			dbg_lines		= saved_dbg_lines;
	if (1) for (u32 it=0; it<dbg_lines.size(); it++)
	{
		RCache.dbg_DrawLINE		(Fidentity,dbg_lines[it].P0,dbg_lines[it].P1,dbg_lines[it].color);
	}
#endif

	// ********************* Debug
	/*
	if (0)		{
		u32		C					= color_rgba	(255,255,255,255);
		float	_w					= float(Device.dwWidth)/3;
		float	_h					= float(Device.dwHeight)/3;

		// draw light-spheres
#ifdef DEBUG
		if (0) for (u32 it=0; it<dbg_spheres.size(); it++)
		{
			Fsphere				S	= dbg_spheres[it].first;
			Fmatrix				M;	
			u32				ccc		= dbg_spheres[it].second.get();
			M.scale					(S.R,S.R,S.R);
			M.translate_over		(S.P);
			RCache.dbg_DrawEllipse	(M,ccc);
			RCache.dbg_DrawAABB		(S.P,.05f,.05f,.05f,ccc);
		}
#endif
		// Draw quater-screen quad textured with our direct-shadow-map-image
		if (1) 
		{
			u32							IX=0,IY=1;
			p0.set						(.5f/_w, .5f/_h);
			p1.set						((_w+.5f)/_w, (_h+.5f)/_h );

			// Fill vertex buffer
			FVF::TL* pv					= (FVF::TL*) RCache.Vertex.Lock	(4,g_combine->vb_stride,Offset);
			pv->set						((IX+0)*_w+EPS,	(IY+1)*_h+EPS,	EPS,	1.f, C, p0.x, p1.y);	pv++;
			pv->set						((IX+0)*_w+EPS,	(IY+0)*_h+EPS,	EPS,	1.f, C, p0.x, p0.y);	pv++;
			pv->set						((IX+1)*_w+EPS,	(IY+1)*_h+EPS,	EPS,	1.f, C, p1.x, p1.y);	pv++;
			pv->set						((IX+1)*_w+EPS,	(IY+0)*_h+EPS,	EPS,	1.f, C, p1.x, p0.y);	pv++;
			RCache.Vertex.Unlock		(4,g_combine->vb_stride);

			// Draw COLOR
			RCache.set_Shader			(s_combine_dbg_0);
			RCache.set_Geometry			(g_combine);
			RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
		}

		// Draw quater-screen quad textured with our accumulator
		if (0)
		{
			u32							IX=1,IY=1;
			p0.set						(.5f/_w, .5f/_h);
			p1.set						((_w+.5f)/_w, (_h+.5f)/_h );

			// Fill vertex buffer
			FVF::TL* pv					= (FVF::TL*) RCache.Vertex.Lock	(4,g_combine->vb_stride,Offset);
			pv->set						((IX+0)*_w+EPS,	(IY+1)*_h+EPS,	EPS,	1.f, C, p0.x, p1.y);	pv++;
			pv->set						((IX+0)*_w+EPS,	(IY+0)*_h+EPS,	EPS,	1.f, C, p0.x, p0.y);	pv++;
			pv->set						((IX+1)*_w+EPS,	(IY+1)*_h+EPS,	EPS,	1.f, C, p1.x, p1.y);	pv++;
			pv->set						((IX+1)*_w+EPS,	(IY+0)*_h+EPS,	EPS,	1.f, C, p1.x, p0.y);	pv++;
			RCache.Vertex.Unlock		(4,g_combine->vb_stride);

			// Draw COLOR
			RCache.set_Shader			(s_combine_dbg_1);
			RCache.set_Geometry			(g_combine);
			RCache.Render				(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
		}
	}
	*/
#ifdef DEBUG
	dbg_spheres.clear	();
	dbg_lines.clear		();
	dbg_planes.clear	();
#endif
}
コード例 #12
0
bool ESceneObjectTool::ExportClimableObjects(SExportStreams* F)
{
	bool bResult                    = true;
    CGeomPartExtractor* extractor   = 0;

    Fbox 		bb;
    if (!GetBox(bb))
        return  false;

    extractor	                    = xr_new<CGeomPartExtractor>();
    extractor->Initialize           (bb,EPS_L,int_max);

    UI->SetStatus	("Export climable objects...");
	// collect verts&&faces
    {
	    SPBItem* pb                 = UI->ProgressStart(m_Objects.size(), "Prepare geometry...");
        for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++)
        {
	        pb->Inc();
            CSceneObject* obj 		= dynamic_cast<CSceneObject*>(*it);
            VERIFY                  (obj);
            if (obj->IsStatic())
            {
                CEditableObject *O 	= obj->GetReference();
                const Fmatrix& T 	= obj->_Transform();
                
                for(EditMeshIt M =O->FirstMesh(); M!=O->LastMesh(); M++)
                    if (!build_mesh	(T, *M, extractor, SGameMtl::flClimable, TRUE))
                    {
                      bResult       = false;
                      break;
                    }
            }
        }
	    UI->ProgressEnd(pb);
    }
    if (!extractor->Process())
        bResult                     = false;

    // export parts
    if (bResult)
    {
    	SBPartVec& parts			= extractor->GetParts();
	    SPBItem* pb                 = UI->ProgressStart(parts.size(),"Export Parts...");
        for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++)
        {
	        pb->Inc                 ();
            SBPart*	P				= *p_it;
        	if (P->Valid())
            {
                // export visual
                AnsiString sn		            = AnsiString().sprintf("clmbl#%d",(p_it-parts.begin()));

				Fvector local_normal	        = {0,0,0};

                LPCSTR mat_name = NULL;
                for (SBFaceVecIt it=P->m_Faces.begin(); it!=P->m_Faces.end(); it++)
                {
                	for (u32 k=0; k<3; k++)
                        local_normal.add	        ((*it)->n[k]);

                    mat_name     = (*it)->surf->_GameMtlName();
                }

                local_normal.normalize_safe		();
                
                // export spawn object
                {
                    AnsiString entity_ref		= "climable_object";
                    ISE_Abstract*	m_Data		= create_entity(entity_ref.c_str()); 	VERIFY(m_Data);
                    ISE_Shape* m_Shape			= m_Data->shape();                      VERIFY(m_Shape);
//					CSE_Visual* m_Visual		= m_Data->visual();	VERIFY(m_Visual);
                    // set params
                    m_Data->set_name			(entity_ref.c_str());
                    m_Data->set_name_replace	(sn.c_str());
                    // set shape
                    CShapeData::shape_def		shape;
                    shape.type					= CShapeData::cfBox;
                    shape.data.box.scale		((P->m_BBox.max.x-P->m_BBox.min.x)*0.5f,
                    							(P->m_BBox.max.y-P->m_BBox.min.y)*0.5f,
                                                (P->m_BBox.max.z-P->m_BBox.min.z)*0.5f);
                    m_Shape->assign_shapes		(&shape,1);
					// orientate object
	          		if (!OrientToNorm(local_normal,P->m_OBB.m_rotate,P->m_OBB.m_halfsize))
                    {
                    	ELog.Msg(mtError,"Invalid climable object found. [%3.2f, %3.2f, %3.2f]",VPUSH(P->m_RefOffset));
					}
                    else
                    {
                        Fmatrix M; M.set			(P->m_OBB.m_rotate.i,P->m_OBB.m_rotate.j,P->m_OBB.m_rotate.k,P->m_OBB.m_translate);
                        M.getXYZ					(P->m_RefRotate); // не i потому что в движке так
                        m_Data->position().set		(P->m_RefOffset); 
                        m_Data->angle().set			(P->m_RefRotate);

                        m_Data->set_additional_info((void*)mat_name);
                        NET_Packet					Packet;
                        m_Data->Spawn_Write			(Packet,TRUE);

                        F->spawn.stream.open_chunk	(F->spawn.chunk++);
                        F->spawn.stream.w			(Packet.B.data,Packet.B.count);
                        F->spawn.stream.close_chunk	();

						if (s_draw_dbg)
                        {
                            Tools->m_DebugDraw.AppendOBB(P->m_OBB);
                            M.transform_dir				(local_normal);
                            Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,local_normal,1.f));
                        }
                    }
                    destroy_entity				(m_Data);
                }
            }else
            {
            	ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin());
            }
        }
	    UI->ProgressEnd     (pb);
    }
    // clean up
    xr_delete               (extractor);

    return                  bResult;
}
コード例 #13
0
ファイル: PHDestroyable.cpp プロジェクト: 2asoft/xray
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())));
		}
	}

}
コード例 #14
0
ファイル: SceneObject.cpp プロジェクト: OLR-xray/OLR-3.0
void CSceneObject::GetFullTransformToLocal( Fmatrix& m )
{
    m.set(_ITransform());
}
コード例 #15
0
ファイル: IKFoot.cpp プロジェクト: AntonioModer/xray-16
void CIKFoot::set_toe(  u16 bones[4] )
{

	VERIFY( Kinematics() );

	m_foot_bone_id = bones[2];
	m_toe_bone_id =	bones[3];

	xr_vector<Fmatrix> binds;
	Kinematics()->LL_GetBindTransform( binds );
	
	const Fmatrix bind_ref	= binds[ bones[m_ref_bone] ];
	const Fmatrix ibind_ref = Fmatrix().invert( bind_ref );

	const Fmatrix bind2		= binds[ bones[2] ] ;
	const Fmatrix ibind2	= Fmatrix().invert( bind2 );

	//const Fmatrix ref_to_b2	= Fmatrix().mul_43( ibind2, bind_ref );
	const Fmatrix b2to_ref	= Fmatrix().mul_43(  ibind_ref, bind2 );

	const Fmatrix bind3		= binds[ bones[3] ] ;
	const Fmatrix ibind3	= Fmatrix().invert( bind3 );

	m_bind_b2_to_b3.mul_43( ibind2, bind3 );
	///////////////////////////////////////////////////////
	Fvector ax ,foot_normal, foot_dir; 
	get_local_vector( 2, foot_normal, m_foot_normal );
	get_local_vector( 2, foot_dir, m_foot_direction );

	//ref_to_b2.transform_tiny( foot_normal, m_foot_normal.v );
	//ref_to_b2.transform_tiny( foot_dir, m_foot_direction.v );

	ax.add( foot_normal, foot_dir );
	ax.normalize();
	///////////////////////////////////////////////////////
	Fvector pos; pos.set( 0, 0, 0 );
	Fmatrix ibind = ibind3;
	envc pred( ibind, ax, pos );
	/////////////////////////////////////////////////////////
	Kinematics()->EnumBoneVertices( pred, bones[3] );
	bind3.transform_tiny( pos );
	ibind2.transform_tiny( pos );
	m_toe_position.v.set( pos );
	/////////////////////////////////////////////////////////
	ibind.set( ibind2 );
	ax.set( foot_normal );
	Kinematics()->EnumBoneVertices( pred, bones[2] );
	m_toe_position.v.x = _max( pos.x, m_toe_position.v.x );
	/////////////////////////////////////////////////////////
	ax.sub( foot_normal, foot_dir );
	ax.normalize();
	pred.start_pos.set(0,0,0);pos.set( 0, 0, 0 );
	Kinematics()->EnumBoneVertices( pred, bones[2] );
	m_heel_position.v = pred.pos	;
	m_heel_position.v.add( Fvector().mul( foot_dir,
		Fvector().sub( m_toe_position.v, pos ).dotproduct( foot_dir ) * 0.2f	) 
	);
	m_heel_position.bone = 2;
	///////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////
	bind2.transform_tiny( m_toe_position.v );
	ibind_ref.transform_tiny( m_toe_position.v );
	m_toe_position.bone = ref_bone();
	/////////////////////////////////////////////////////////

	get_local_vector( foot_normal, m_foot_normal );
	m_foot_width = ( Fvector().sub( m_toe_position.v, b2to_ref.c ) ).dotproduct(  foot_normal );


}
コード例 #16
0
ファイル: IKFoot.cpp プロジェクト: AntonioModer/xray-16
bool CIKFoot::GetFootStepMatrix( ik_goal_matrix &m, const Fmatrix &g_anim, const  SIKCollideData &cld, bool collide, bool rotation, bool b_make_shift/*=true*/ )const
{
	const Fmatrix global_anim = g_anim;
	Fvector	local_point;		ToePosition( local_point );													//toe position in bone[2] space
	Fvector	global_point;		global_anim.transform_tiny( global_point, local_point );						//non collided toe in global space
	Fvector foot_normal;		FootNormal( foot_normal );
	global_anim.transform_dir( foot_normal );
#ifdef DEBUG
		//if( ph_dbg_draw_mask.test( phDbgDrawIKGoal ) )
		//{
		//	DBG_DrawLine( global_point, Fvector().add( global_point, foot_normal ), D3DCOLOR_XRGB( 0, 255, 255) );
		//}
#endif
	if( cld.m_collide_point == ik_foot_geom::heel || cld.m_collide_point == ik_foot_geom::side )
	{
		Fmatrix foot;ref_bone_to_foot( foot, g_anim );
		Fvector heel;
		HeelPosition( heel );
		foot.transform_tiny(global_point, heel );
#ifdef DEBUG
		if( ph_dbg_draw_mask.test( phDbgDrawIKGoal ) )
			DBG_DrawPoint( global_point, 0.01, D3DCOLOR_XRGB( 0, 255, 255));
#endif
		Fmatrix foot_to_ref;
		ref_bone_to_foot_transform(foot_to_ref).transform_tiny(local_point, heel );
	}

	float	dtoe_tri		=-cld.m_plane.d - cld.m_plane.n.dotproduct( global_point );	
	if(  !cld.collided ||  _abs( dtoe_tri ) > collide_dist )
	{
		m.set( global_anim, ik_goal_matrix::cl_free );
		return false;
	}

	Fplane p = cld.m_plane;
	Fmatrix xm; xm.set( global_anim );
	ik_goal_matrix::e_collide_state cl_state = ik_goal_matrix::cl_undefined;
	if( rotation )//!collide || ik_allign_free_foot
		cl_state = rotate( xm, p, foot_normal, global_point, collide );

	if( b_make_shift && make_shift( xm, local_point, collide, p, cld.m_pick_dir ) )
		switch( cl_state )
		{
			case ik_goal_matrix::cl_aligned		:					break;
			case ik_goal_matrix::cl_undefined	:
			case ik_goal_matrix::cl_free		:
					cl_state = ik_goal_matrix::cl_translational;	break;
			case ik_goal_matrix::cl_rotational:
					cl_state = ik_goal_matrix::cl_mixed;			break;
			default:		NODEFAULT;
			
		}
	else if( cl_state == ik_goal_matrix::cl_undefined )
			cl_state = ik_goal_matrix::cl_free;
	

	VERIFY( _valid( xm ) );
	m.set( xm, cl_state );
#ifdef DEBUG
	if(ph_dbg_draw_mask.test( phDbgDrawIKGoal ))
	{
		DBG_DrawPoint( global_point, 0.03f, D3DCOLOR_RGBA( 255, 0, 0, 255 ) );
	}
	if(!fsimilar( _abs( DET( g_anim ) - 1.f ), _abs( DET( m.get() ) - 1.f ), 0.001f ) )
		Msg("scale g_anim: %f scale m: %f ",  DET( g_anim ) ,  DET( m.get() ) );
#endif

	return true;
}
コード例 #17
0
ファイル: BastArtifact.cpp プロジェクト: OLR-xray/OLR-3.0
void CBastArtefact::UpdateCLChild() 
{
	//Log						("--- A - CBastArtefact",*cName());
	//Log						("--- A - CBastArtefact",renderable.xform);

	//современем энергия по немногу тоже уменьшается
	if(m_fEnergy>0) m_fEnergy -= m_fEnergyDecreasePerTime*Device.fTimeDelta;

	if (getVisible() && m_pPhysicsShell) {
		if(m_bStrike) {
			//выбрать жертву, если она еще не выбрана
			if(!m_AliveList.empty() && m_AttakingEntity == NULL) {
				CEntityAlive* pEntityToHit = NULL;
				if(m_AliveList.size()>1)
				{
					do
					{
						int rnd = ::Random.randI(m_AliveList.size());
						pEntityToHit = m_AliveList[rnd];
					} while (pEntityToHit == m_pHitedEntity);
				}
				else
				{
					pEntityToHit = m_AliveList.front();
				}

				m_AttakingEntity = pEntityToHit;
			}
		}
		
		if(m_AttakingEntity)
		{
			if(m_AttakingEntity->g_Alive() && m_fEnergy>m_fStrikeImpulse)
			{
				m_fEnergy -= m_fStrikeImpulse;

				//бросить артефакт на выбранную цель
				Fvector dir;
				m_AttakingEntity->Center(dir);
				dir.sub(this->Position()); 
				dir.y += ::Random.randF(-0.05f, 0.5f);
		
				m_pPhysicsShell->applyImpulse(dir, 
								  m_fStrikeImpulse * Device.fTimeDelta *
								  m_pPhysicsShell->getMass());
			}
			else
			{
				m_AttakingEntity = NULL;
				m_bStrike = false;
			}
		}



		if(m_fEnergy>0 && ::Random.randF(0.f, 1.0f)<(m_fEnergy/(m_fStrikeImpulse*100.f)))
		{
			CParticlesObject* pStaticPG;
			pStaticPG = CParticlesObject::Create(*m_sParticleName,TRUE);
			Fmatrix pos; 
			pos.set(XFORM()); 
			Fvector vel; 
			//vel.sub(Position(),ps_Element(0).vPosition); 
			//vel.div((Level().timeServer()-ps_Element(0).dwTime)/1000.f);
			vel.set(0,0,0);
			pStaticPG->UpdateParent(pos, vel); 
			pStaticPG->Play();
		}

	} 
	else if(H_Parent()) XFORM().set(H_Parent()->XFORM());
}