本文整理汇总了C++中Fvector::div方法的典型用法代码示例。如果您正苦于以下问题:C++ Fvector::div方法的具体用法?C++ Fvector::div怎么用?C++ Fvector::div使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Fvector
的用法示例。
在下文中一共展示了Fvector::div方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: closestPointOnLine
IC void closestPointOnLine(Fvector& res, const Fvector& a, const Fvector& b, const Fvector& p)
{
// Determine t (the length of the xr_vector from ‘a’ to ‘p’)
Fvector c;
c.sub(p,a);
Fvector V;
V.sub(b,a);
float d = V.magnitude();
V.div(d);
float t = V.dotproduct(c);
// Check to see if ‘t’ is beyond the extents of the line segment
if (t <= 0.0f) {
res.set(a);
return;
}
if (t >= d) {
res.set(b);
return;
}
// Return the point between ‘a’ and ‘b’
// set length of V to t. V is normalized so this is easy
res.mad (a,V,t);
}
示例2: show_debug_info
CBaseMonster::SDebugInfo CController::show_debug_info()
{
CBaseMonster::SDebugInfo info = inherited::show_debug_info();
if (!info.active) return CBaseMonster::SDebugInfo();
// Draw Controlled Lines
DBG().level_info(this).clear();
Fvector my_pos = Position();
my_pos.y += 1.5f;
for (u32 i=0; i < m_controlled_objects.size(); i++)
{
Fvector enemy_pos = m_controlled_objects[i]->Position();
Fvector dir;
dir.sub(enemy_pos, Position());
dir.div(2.f);
Fvector new_pos;
new_pos.add(Position(),dir);
new_pos.y += 10.f;
enemy_pos.y += 1.0f;
DBG().level_info(this).add_item(my_pos, new_pos, D3DCOLOR_XRGB(0,255,255));
DBG().level_info(this).add_item(enemy_pos, new_pos, D3DCOLOR_XRGB(0,255,255));
}
return CBaseMonster::SDebugInfo();
}
示例3: OnMove
void CCustomZone::OnMove()
{
if(m_dwLastTimeMoved == 0)
{
m_dwLastTimeMoved = Device.dwTimeGlobal;
m_vPrevPos.set(Position());
}
else
{
float time_delta = float(Device.dwTimeGlobal - m_dwLastTimeMoved)/1000.f;
m_dwLastTimeMoved = Device.dwTimeGlobal;
Fvector vel;
if(fis_zero(time_delta))
vel = zero_vel;
else
{
vel.sub(Position(), m_vPrevPos);
vel.div(time_delta);
}
if (m_pIdleParticles)
m_pIdleParticles->UpdateParent(XFORM(), vel);
if(m_pLight && m_pLight->get_active())
m_pLight->set_position(Position());
if(m_pIdleLight && m_pIdleLight->get_active())
m_pIdleLight->set_position(Position());
}
}
示例4:
void CPortal::OnRender ()
{
if (psDeviceFlags.is(rsOcclusionDraw)){
VERIFY (poly.size());
// draw rect
using LVec = xr_vector<FVF::L>;
using LVecIt = LVec::iterator;
static LVec V; V.resize(poly.size()+2);
Fvector C = {0,0,0};
for (u32 k=0; k<poly.size(); k++){ C.add(poly[k]); V[k+1].set(poly[k],0x800000FF);}
V.back().set (poly[0],0x800000FF);
C.div ((float)poly.size());
V[0].set (C,0x800000FF);
RCache.set_xform_world(Fidentity);
// draw solid
RCache.set_Shader (dxRenderDeviceRender::Instance().m_SelectionShader);
RCache.dbg_Draw (D3DPT_TRIANGLEFAN,&*V.begin(),V.size()-2);
// draw wire
if (bDebug){
RImplementation.rmNear();
}else{
Device.SetNearer(TRUE);
}
RCache.set_Shader (dxRenderDeviceRender::Instance().m_WireShader);
RCache.dbg_Draw (D3DPT_LINESTRIP,&*(V.begin()+1),V.size()-2);
if (bDebug){
RImplementation.rmNormal();
}else{
Device.SetNearer(FALSE);
}
}
}
示例5: msimulator_ResolveStuck
//-----------------------------------------------------------------------------
void msimulator_ResolveStuck(SCollisionData& cl, Fvector& position)
{
// intersection data
Fvector polyIPoint; // polygon intersection point
Fvector stuckDir;
int stuckCount;
float dist;
float safe_R = 1.f + EPS_L*2;//psSqueezeVelocity*Device.fTimeDelta;
for (int passes=0; passes<psCollideActStuckDepth; passes++)
{
// initialize
stuckDir.set (0,0,0);
stuckCount = 0;
// for all faces
for (u32 i_t=0; i_t!=clContactedT.size(); i_t++)
{
cl_tri& T=clContactedT[i_t];
Fvector N_inv;
N_inv.invert(T.N);
// find plane intersection point by shooting a ray from the
// sphere intersection point along the planes normal.
if (CDB::TestRayTri2(position,N_inv,T.p,dist)) {
// calculate plane intersection point
polyIPoint.mad(position,N_inv,dist);
} else {
// calculate plane intersection point
Fvector tmp;
tmp.mad(position,N_inv,dist);
closestPointOnTriangle(polyIPoint, T, tmp);
}
if (CheckPointInSphere(polyIPoint, position, safe_R))
{
Fvector dir;
dir.sub(position,polyIPoint);
float len = dir.magnitude();
dir.mul( (safe_R-len)/len );
stuckDir.add(dir);
stuckCount++;
}
}
if (stuckCount) {
stuckDir.div(float(stuckCount));
position.add(stuckDir);
if (stuckDir.magnitude()<EPS) break;
} else break;
}
}
示例6:
void IWriter::w_sdir (const Fvector& D)
{
Fvector C;
float mag = D.magnitude();
if (mag>EPS_S) {
C.div (D,mag);
} else {
C.set (0,0,1);
mag = 0;
}
w_dir (C);
w_float (mag);
}
示例7:
IC float SqrDistance2Segment(const Fvector& P, const Fvector& A, const Fvector& B)
{
// Determine t (the length of the vector from ‘a’ to ‘p’)
Fvector c; c.sub(P,A);
Fvector V; V.sub(B,A);
float d = V.magnitude ();
V.div (d);
float t = V.dotproduct (c);
// Check to see if ‘t’ is beyond the extents of the line segment
if (t <= 0.0f) return P.distance_to_sqr(A);
if (t >= d) return P.distance_to_sqr(B);
// Return the point between ‘a’ and ‘b’
// set length of V to t. V is normalized so this is easy
Fvector R; R.mad (A,V,t);
return P.distance_to_sqr(R);
}
示例8:
void CGlowManager::render_sw ()
{
// 0. save main view and disable
CObject* o_main = g_pGameLevel->CurrentViewEntity();
// 1. Test some number of glows
Fvector start = Device.vCameraPosition;
for (int i=0; i<ps_r1_GlowsPerFrame; i++,dwTestID++)
{
u32 ID = dwTestID%Selected.size();
CGlow& G = *( (CGlow*)Selected[ID]._get() );
if (G.dwFrame=='test') break;
G.dwFrame = 'test';
Fvector dir;
dir.sub (G.spatial.sphere.P,start); float range = dir.magnitude();
if (range>EPS_S) {
dir.div (range);
G.bTestResult = g_pGameLevel->ObjectSpace.RayTest(start,dir,range,collide::rqtBoth,&G.RayCache,o_main);
}
}
// 2. Render selected
render_selected ();
}
示例9: WORD
BOOL CreateNode(Fvector& vAt, vertex& N)
{
// *** Query and cache polygons for ray-casting
Fvector PointUp; PointUp.set(vAt); PointUp.y += RCAST_Depth; SnapXZ (PointUp);
Fvector PointDown; PointDown.set(vAt); PointDown.y -= RCAST_Depth; SnapXZ (PointDown);
Fbox BB; BB.set (PointUp,PointUp); BB.grow(g_params.fPatchSize/2); // box 1
Fbox B2; B2.set (PointDown,PointDown); B2.grow(g_params.fPatchSize/2); // box 2
BB.merge(B2 );
BoxQuery(BB,false );
u32 dwCount = XRC.r_count();
if (dwCount==0) {
// Log("chasm1");
return FALSE; // chasm?
}
// *** Transfer triangles and compute sector
R_ASSERT(dwCount<RCAST_MaxTris);
static svector<tri,RCAST_MaxTris> tris; tris.clear();
for (u32 i=0; i<dwCount; i++)
{
tri& D = tris.last();
CDB::RESULT &rp = XRC.r_begin()[i];
CDB::TRI& T = *(Level.get_tris()+rp.id);
D.v[0].set (rp.verts[0]);
D.v[1].set (rp.verts[1]);
D.v[2].set (rp.verts[2]);
D.sector = T.sector;
D.N.mknormal(D.v[0],D.v[1],D.v[2]);
if (D.N.y<=0) continue;
tris.inc ();
}
if (tris.size()==0) {
// Log("chasm2");
return FALSE; // chasm?
}
// *** Perform ray-casts and calculate sector
WORD Sector = 0xfffe; // mark as first time
static svector<Fvector,RCAST_Total> points; points.clear();
static svector<Fvector,RCAST_Total> normals; normals.clear();
Fvector P,D; D.set(0,-1,0);
float coeff = 0.5f*g_params.fPatchSize/float(RCAST_Count);
for (int x=-RCAST_Count; x<=RCAST_Count; x++)
{
P.x = vAt.x + coeff*float(x);
for (int z=-RCAST_Count; z<=RCAST_Count; z++) {
P.z = vAt.z + coeff*float(z);
P.y = vAt.y + 10.f;
float tri_min_range = flt_max;
int tri_selected = -1;
float range,u,v;
for (i=0; i<u32(tris.size()); i++)
{
if (CDB::TestRayTri(P,D,tris[i].v,u,v,range,false))
{
if (range<tri_min_range) {
tri_min_range = range;
tri_selected = i;
}
}
}
if (tri_selected>=0) {
P.y -= tri_min_range;
points.push_back(P);
normals.push_back(tris[tri_selected].N);
WORD TS = WORD(tris[tri_selected].sector);
if (Sector==0xfffe) Sector = TS;
else if (Sector!=TS) Sector=InvalidSector;
}
}
}
if (points.size()<3) {
// Msg ("Failed to create node at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
return FALSE;
}
if (float(points.size())/float(RCAST_Total) < 0.7f) {
// Msg ("Partial chasm at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
return FALSE;
}
// *** Calc normal
Fvector vNorm;
vNorm.set(0,0,0);
for (u32 n=0; n<normals.size(); n++)
vNorm.add(normals[n]);
vNorm.div(float(normals.size()));
vNorm.normalize();
/*
{
// second algorithm (Magic)
Fvector N,O;
N.set(vNorm);
O.set(points[0]);
//.........这里部分代码省略.........
示例10:
//--------------------------------------------------------------------
void PDomain::Render (u32 clr, const Fmatrix& parent)
{
if (!flags.is(flRenderable)) return;
u32 clr_s = subst_alpha (clr,0x60);
u32 clr_w = subst_alpha (clr,0xff);
RCache.set_xform_world (parent);
switch(type){
case PDPoint:
EDevice.SetShader (EDevice.m_WireShader);
DU_impl.DrawCross (v[0], 0.05f,0.05f,0.05f, 0.05f,0.05f,0.05f, clr_w);
break;
case PDLine:
EDevice.SetShader (EDevice.m_WireShader);
DU_impl.DrawCross (v[0], 0.05f,0.05f,0.05f, 0.05f,0.05f,0.05f, clr_w);
DU_impl.DrawCross (v[1], 0.05f,0.05f,0.05f, 0.05f,0.05f,0.05f, clr_w);
DU_impl.DrawLine (v[0], v[1], clr_w);
break;
case PDTriangle:
EDevice.SetShader (EDevice.m_SelectionShader);
DU_impl.DrawFace (v[0], v[1], v[2], clr_s, clr_w, true, true);
break;
case PDPlane:{
EDevice.SetShader (EDevice.m_SelectionShader);
Fvector2 sz = {100.f,100.f};
DU_impl.DrawPlane (v[0],v[1],sz,clr_s,clr_w,true,true,true);
}break;
case PDBox:
EDevice.SetShader (EDevice.m_SelectionShader);
DU_impl.DrawAABB (v[0], v[1], clr_s, clr_w, true, true);
break;
case PDSphere:
DU_impl.DrawSphere (parent, v[0], f[4], clr_s, clr_w, true, true);
DU_impl.DrawSphere (parent, v[0], f[3], clr_s, clr_w, true, true);
break;
case PDCylinder:{
Fvector c,d;
float h = d.sub(v[1],v[0]).magnitude();
c.add (v[0],v[1]).div(2.f);
if (!fis_zero(h)){
d.div (h);
DU_impl.DrawCylinder (parent, c, d, h, f[6], clr_s, clr_w, true, true);
DU_impl.DrawCylinder (parent, c, d, h, f[7], clr_s, clr_w, true, true);
}
}break;
case PDCone:{
Fvector d;
float h = d.sub(v[1],v[0]).magnitude();
if (!fis_zero(h)){
d.div (h);
DU_impl.DrawCone (parent, v[0], d, h, f[6], clr_s, clr_w, true, true);
DU_impl.DrawCone (parent, v[0], d, h, f[7], clr_s, clr_w, true, true);
}
}break;
case PDBlob:
EDevice.SetShader (EDevice.m_WireShader);
DU_impl.DrawCross (v[0], f[3],f[3],f[3], f[3],f[3],f[3], clr);
break;
case PDDisc:
DU_impl.DrawCylinder (parent, v[0], v[1], 0.f, f[6], clr_s, clr_w, true, true);
DU_impl.DrawCylinder (parent, v[0], v[1], 0.f, f[7], clr_s, clr_w, true, true);
break;
case PDRectangle:
DU_impl.DrawRectangle (v[0], v[1], v[2], clr_s, clr_w, true, true);
break;
}
}
示例11: float
virtual void Execute()
{
CDB::COLLIDER DB;
DB.ray_options (CDB::OPT_CULL);
xr_vector<RC> cache;
{
RC rc;
rc.C[0].set (0,0,0);
rc.C[1].set (0,0,0);
rc.C[2].set (0,0,0);
cache.assign (g_nodes.size()*2,rc);
}
FPU::m24r ();
Query Q;
Q.Begin (g_nodes.size());
for (u32 N=Nstart; N<Nend; N++)
{
// initialize process
thProgress = float(N-Nstart)/float(Nend-Nstart);
vertex& BaseNode= g_nodes[N];
Fvector& BasePos = BaseNode.Pos;
Fvector TestPos = BasePos; TestPos.y+=cover_height;
float c_total [8] = {0,0,0,0,0,0,0,0};
float c_passed[8] = {0,0,0,0,0,0,0,0};
// perform volumetric query
Q.Init (BasePos);
Q.Perform (N);
// main cycle: trace rays and compute counts
for (Nearest_it it=Q.q_List.begin(); it!=Q.q_List.end(); it++)
{
// calc dir & range
u32 ID = *it;
R_ASSERT (ID<g_nodes.size());
if (N==ID) continue;
vertex& N = g_nodes[ID];
Fvector& Pos = N.Pos;
Fvector Dir;
Dir.sub (Pos,BasePos);
float range = Dir.magnitude();
Dir.div (range);
// raytrace
int sector = calcSphereSector(Dir);
c_total [sector] += 1.f;
c_passed [sector] += rayTrace (&DB, TestPos, Dir, range, cache[ID].C); //
}
Q.Clear ();
// analyze probabilities
float value [8];
for (int dirs=0; dirs<8; dirs++) {
R_ASSERT(c_passed[dirs]<=c_total[dirs]);
if (c_total[dirs]==0) value[dirs] = 0;
else value[dirs] = float(c_passed[dirs])/float(c_total[dirs]);
clamp(value[dirs],0.f,1.f);
}
BaseNode.cover [0] = (value[2]+value[3]+value[4]+value[5])/4.f; clamp(BaseNode.cover[0],0.f,1.f); // left
BaseNode.cover [1] = (value[0]+value[1]+value[2]+value[3])/4.f; clamp(BaseNode.cover[1],0.f,1.f); // forward
BaseNode.cover [2] = (value[6]+value[7]+value[0]+value[1])/4.f; clamp(BaseNode.cover[2],0.f,1.f); // right
BaseNode.cover [3] = (value[4]+value[5]+value[6]+value[7])/4.f; clamp(BaseNode.cover[3],0.f,1.f); // back
}
}
示例12: ExecuteCollision
void CPEDef::ExecuteCollision(PAPI::Particle* particles, u32 p_cnt, float dt, CParticleEffect* owner, CollisionCallback cb)
{
pVector pt,n;
// Must traverse list in reverse order so Remove will work
for(int i = p_cnt-1; i >= 0; i--){
Particle &m = particles[i];
bool pick_needed;
int pick_cnt=0;
do{
pick_needed = false;
Fvector dir;
dir.sub (m.pos,m.posB);
float dist = dir.magnitude();
if (dist>=EPS){
dir.div (dist);
#ifdef _EDITOR
if (Tools->RayPick(m.posB,dir,dist,&pt,&n)){
#else
collide::rq_result RQ;
collide::rq_target RT = m_Flags.is(dfCollisionDyn)?collide::rqtBoth:collide::rqtStatic;
if (g_pGameLevel->ObjectSpace.RayPick(m.posB,dir,dist,RT,RQ,NULL)){
pt.mad (m.posB,dir,RQ.range);
if (RQ.O){
n.set(0.f,1.f,0.f);
}else{
CDB::TRI* T = g_pGameLevel->ObjectSpace.GetStaticTris()+RQ.element;
Fvector* verts = g_pGameLevel->ObjectSpace.GetStaticVerts();
n.mknormal(verts[T->verts[0]],verts[T->verts[1]],verts[T->verts[2]]);
}
#endif
pick_cnt++;
if (cb&&(pick_cnt==1)) if (!cb(owner,m,pt,n)) break;
if (m_Flags.is(dfCollisionDel)){
ParticleManager()->RemoveParticle(owner->m_HandleEffect,i);
}else{
// Compute tangential and normal components of velocity
float nmag = m.vel * n;
pVector vn(n * nmag); // Normal Vn = (V.N)N
pVector vt(m.vel - vn); // Tangent Vt = V - Vn
// Compute _new velocity heading out:
// Don't apply friction if tangential velocity < cutoff
if(vt.length2() <= m_fCollideSqrCutoff){
m.vel = vt - vn * m_fCollideResilience;
}else{
m.vel = vt * m_fCollideOneMinusFriction - vn * m_fCollideResilience;
}
m.pos = m.posB + m.vel * dt;
pick_needed = true;
}
}
}else{
m.pos = m.posB;
}
}while(pick_needed&&(pick_cnt<2));
}
}
//------------------------------------------------------------------------------
// I/O part
//------------------------------------------------------------------------------
BOOL CPEDef::Load(IReader& F)
{
R_ASSERT (F.find_chunk(PED_CHUNK_VERSION));
u16 version = F.r_u16();
if (version!=PED_VERSION)
return FALSE;
R_ASSERT (F.find_chunk(PED_CHUNK_NAME));
F.r_stringZ (m_Name);
R_ASSERT (F.find_chunk(PED_CHUNK_EFFECTDATA));
m_MaxParticles = F.r_u32();
{
u32 action_list = F.find_chunk(PED_CHUNK_ACTIONLIST);
R_ASSERT(action_list);
m_Actions.w (F.pointer(),action_list);
}
F.r_chunk (PED_CHUNK_FLAGS,&m_Flags);
if (m_Flags.is(dfSprite))
{
R_ASSERT (F.find_chunk(PED_CHUNK_SPRITE));
F.r_stringZ (m_ShaderName);
F.r_stringZ (m_TextureName);
}
if (m_Flags.is(dfFramed))
{
R_ASSERT (F.find_chunk(PED_CHUNK_FRAME));
F.r (&m_Frame,sizeof(SFrame));
}
if (m_Flags.is(dfTimeLimit))
{
R_ASSERT(F.find_chunk(PED_CHUNK_TIMELIMIT));
//.........这里部分代码省略.........
示例13:
void Vision::o_trace (Fvector& P, float dt, float vis_threshold) {
RQR.r_clear ();
xr_vector<feel_visible_Item>::iterator I=feel_visible.begin(),E=feel_visible.end();
for (; I!=E; I++){
if (0==I->O->CFORM()) { I->fuzzy = -1; continue; }
// verify relation
if (positive(I->fuzzy) && I->O->Position().similar(I->cp_LR_dst,lr_granularity) && P.similar(I->cp_LR_src,lr_granularity))
continue;
I->cp_LR_dst = I->O->Position();
I->cp_LR_src = P;
// Fetch data
Fvector OP;
Fmatrix mE;
const Fbox& B = I->O->CFORM()->getBBox();
const Fmatrix& M = I->O->XFORM();
// Build OBB + Ellipse and X-form point
Fvector c,r;
Fmatrix T,mR,mS;
B.getcenter (c);
B.getradius (r);
T.translate (c);
mR.mul_43 (M,T);
mS.scale (r);
mE.mul_43 (mR,mS);
mE.transform_tiny (OP,I->cp_LP);
I->cp_LAST = OP;
//
Fvector D;
D.sub (OP,P);
float f = D.magnitude();
if (f>fuzzy_guaranteed){
D.div (f);
// setup ray defs & feel params
collide::ray_defs RD (P,D,f,CDB::OPT_CULL,collide::rq_target(collide::rqtStatic|collide::rqtObstacle));
SFeelParam feel_params (this,&*I,vis_threshold);
// check cache
if (I->Cache.result&&I->Cache.similar(P,D,f)){
// similar with previous query
feel_params.vis = I->Cache_vis;
// Log("cache 0");
}else{
float _u,_v,_range;
if (CDB::TestRayTri(P,D,I->Cache.verts,_u,_v,_range,false)&&(_range>0 && _range<f)) {
feel_params.vis = 0.f;
// Log("cache 1");
}else{
// cache outdated. real query.
VERIFY(!fis_zero(RD.dir.square_magnitude()));
if (g_pGameLevel->ObjectSpace.RayQuery (RQR, RD, feel_vision_callback, &feel_params, NULL, NULL)) {
I->Cache_vis = feel_params.vis ;
I->Cache.set (P,D,f,TRUE ) ;
}else{
I->Cache.set (P,D,f,FALSE) ;
}
// Log("query");
}
}
// Log("Vis",feel_params.vis);
if (feel_params.vis<feel_params.vis_threshold){
// INVISIBLE, choose next point
I->fuzzy -= fuzzy_update_novis*dt;
clamp (I->fuzzy,-.5f,1.f);
I->cp_LP.random_dir ();
I->cp_LP.mul (.7f);
}else{
// VISIBLE
I->fuzzy += fuzzy_update_vis*dt;
clamp (I->fuzzy,-.5f,1.f);
}
}
else {
// VISIBLE, 'cause near
I->fuzzy += fuzzy_update_vis*dt;
clamp (I->fuzzy,-.5f,1.f);
}
}
}
示例14: CreateNode
//.........这里部分代码省略.........
int tri_selected = -1;
float range,u,v;
for (i=0; i<DWORD(tris.size()); i++){
if (ETOOLS::TestRayTriA(P,D,tris[i].v,u,v,range,false)){
if (range<tri_min_range){
tri_min_range = range;
tri_selected = i;
}
}
}
if (tri_selected>=0) {
P.y -= tri_min_range;
points.push_back(P);
normals.push_back(tris[tri_selected].N);
}
}
}
if (points.size()<3) {
// Msg ("Failed to create node at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
return FALSE;
}
//.
float rc_lim = bIC?0.015f:0.7f;
if (float(points.size())/float(RCAST_Total) < rc_lim) {
// Msg ("Partial chasm at [%f,%f,%f].",vAt.x,vAt.y,vAt.z);
return FALSE;
}
// *** Calc normal
Fvector vNorm;
vNorm.set(0,0,0);
for (DWORD n=0; n<normals.size(); n++)
vNorm.add(normals[n]);
vNorm.div(float(normals.size()));
vNorm.normalize();
/*
{
// second algorithm (Magic)
Fvector N,O;
N.set(vNorm);
O.set(points[0]);
Mgc::OrthogonalPlaneFit(
points.size(),(Mgc::Vector3*)points.begin(),
*((Mgc::Vector3*)&O),
*((Mgc::Vector3*)&N)
);
if (N.y<0) N.invert();
N.normalize();
vNorm.lerp(vNorm,N,.3f);
vNorm.normalize();
}
*/
// *** Align plane
Fvector vOffs;
vOffs.set(0,-1000,0);
Fplane PL; PL.build(vOffs,vNorm);
for (DWORD p=0; p<points.size(); p++)
{
float dist = PL.classify(points[p]);
if (dist>0) {
vOffs = points[p];
PL.build(vOffs,vNorm);
}
}
示例15: Render
void CParticleEffect::Render(float )
{
u32 dwOffset,dwCount;
// Get a pointer to the particles in gp memory
PAPI::Particle* particles;
u32 p_cnt;
ParticleManager()->GetParticles(m_HandleEffect,particles,p_cnt);
if(p_cnt>0){
if (m_Def&&m_Def->m_Flags.is(CPEDef::dfSprite)){
FVF::LIT* pv_start = (FVF::LIT*)RCache.Vertex.Lock(p_cnt*4*4,geom->vb_stride,dwOffset);
FVF::LIT* pv = pv_start;
for(u32 i = 0; i < p_cnt; i++){
PAPI::Particle &m = particles[i];
Fvector2 lt,rb;
lt.set (0.f,0.f);
rb.set (1.f,1.f);
if (m_Def->m_Flags.is(CPEDef::dfFramed)) m_Def->m_Frame.CalculateTC(iFloor(float(m.frame)/255.f),lt,rb);
float r_x = m.size.x*0.5f;
float r_y = m.size.y*0.5f;
if (m_Def->m_Flags.is(CPEDef::dfVelocityScale)){
float speed = m.vel.magnitude();
r_x += speed*m_Def->m_VelocityScale.x;
r_y += speed*m_Def->m_VelocityScale.y;
}
if (m_Def->m_Flags.is(CPEDef::dfAlignToPath)){
float speed = m.vel.magnitude();
if ((speed<EPS_S)&&m_Def->m_Flags.is(CPEDef::dfWorldAlign)){
Fmatrix M;
M.setXYZ (m_Def->m_APDefaultRotation);
if (m_RT_Flags.is(flRT_XFORM)){
Fvector p;
m_XFORM.transform_tiny(p,m.pos);
M.mulA_43 (m_XFORM);
FillSprite (pv,M.k,M.i,p,lt,rb,r_x,r_y,m.color,m.rot.x);
}else{
FillSprite (pv,M.k,M.i,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x);
}
}else if ((speed>=EPS_S)&&m_Def->m_Flags.is(CPEDef::dfFaceAlign)){
Fmatrix M; M.identity();
M.k.div (m.vel,speed);
M.j.set (0,1,0); if (_abs(M.j.dotproduct(M.k))>.99f) M.j.set(0,0,1);
M.i.crossproduct (M.j,M.k); M.i.normalize ();
M.j.crossproduct (M.k,M.i); M.j.normalize ();
if (m_RT_Flags.is(flRT_XFORM)){
Fvector p;
m_XFORM.transform_tiny(p,m.pos);
M.mulA_43 (m_XFORM);
FillSprite (pv,M.j,M.i,p,lt,rb,r_x,r_y,m.color,m.rot.x);
}else{
FillSprite (pv,M.j,M.i,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x);
}
}else{
Fvector dir;
if (speed>=EPS_S) dir.div (m.vel,speed);
else dir.setHP(-m_Def->m_APDefaultRotation.y,-m_Def->m_APDefaultRotation.x);
if (m_RT_Flags.is(flRT_XFORM)){
Fvector p,d;
m_XFORM.transform_tiny (p,m.pos);
m_XFORM.transform_dir (d,dir);
FillSprite (pv,p,d,lt,rb,r_x,r_y,m.color,m.rot.x);
}else{
FillSprite (pv,m.pos,dir,lt,rb,r_x,r_y,m.color,m.rot.x);
}
}
}else{
if (m_RT_Flags.is(flRT_XFORM)){
Fvector p;
m_XFORM.transform_tiny (p,m.pos);
FillSprite (pv,Device.vCameraTop,Device.vCameraRight,p,lt,rb,r_x,r_y,m.color,m.rot.x);
}else{
FillSprite (pv,Device.vCameraTop,Device.vCameraRight,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x);
}
}
}
dwCount = u32(pv-pv_start);
RCache.Vertex.Unlock(dwCount,geom->vb_stride);
if (dwCount) {
RCache.set_xform_world (Fidentity);
RCache.set_Geometry (geom);
// u32 cm = RCache.get_CullMode();
RCache.set_CullMode (m_Def->m_Flags.is(CPEDef::dfCulling)?(m_Def->m_Flags.is(CPEDef::dfCullCCW)?CULL_CCW:CULL_CW):CULL_NONE);
RCache.Render (D3DPT_TRIANGLELIST,dwOffset,0,dwCount,0,dwCount/2);
RCache.set_CullMode (CULL_CCW );
}
}
}
}