void ESceneAIMapTool::hash_FillFromNodes() { for (AINodeIt it=m_Nodes.begin(); it!=m_Nodes.end(); it++){ AINodeVec* V = HashMap((*it)->Pos); R_ASSERT2(V,"AINode position out of bounds."); V->push_back (*it); } }
void RegisterNode(vertex& N) { u32 ID = g_nodes.size(); g_nodes.push_back(N); HashMap(N.Pos).push_back(ID); }
SAINode* ESceneAIMapTool::FindNode(Fvector& vAt, float eps) { AINodeVec* V = HashMap(vAt); if (!V) return 0; for (AINodeIt I=V->begin(); I!=V->end(); I++){ SAINode* N = *I; if (vAt.similar(N->Pos,eps)) return N; } return 0; }
u32 FindNode(Fvector& vAt) { float eps = 0.05f; vecDW& V = HashMap(vAt); for (vecDW_it I=V.begin(); I!=V.end(); I++) { vertex& N = g_nodes[*I]; if (vAt.similar(N.Pos,eps)) return *I; } return InvalidNode; }
int ESceneAIMapTool::RemoveOutOfBoundsNodes() { int count = 0; for (int k=0; k<(int)m_Nodes.size(); k++){ SAINode* N = m_Nodes[k]; AINodeVec* V = HashMap(N->Pos); if (!V){ m_Nodes.erase(m_Nodes.begin()+k); k--; count++; } } return count; }
SAINode* ESceneAIMapTool::FindNeighbor(SAINode* N, int side, bool bIgnoreConstraints) { Fvector Pos; Pos.set (N->Pos); SnapXZ (Pos,m_Params.fPatchSize); switch (side){ case 0: Pos.x -= m_Params.fPatchSize; break; case 1: Pos.z += m_Params.fPatchSize; break; case 2: Pos.x += m_Params.fPatchSize; break; case 3: Pos.z -= m_Params.fPatchSize; break; } AINodeVec* nodes = HashMap(Pos); SAINode* R = 0; if (nodes) if (bIgnoreConstraints){ float dy= flt_max; for (AINodeIt I=nodes->begin(); I!=nodes->end(); I++) if (fsimilar((*I)->Pos.x,Pos.x,EPS_L)&&fsimilar((*I)->Pos.z,Pos.z,EPS_L)){ float _dy = _abs((*I)->Pos.y-Pos.y); if (_dy<dy){dy=_dy; R=*I;} } }else{ SAINode* R_up = 0; SAINode* R_down = 0; float dy_up = flt_max; float dy_down = flt_max; for (AINodeIt I=nodes->begin(); I!=nodes->end(); I++){ if (fsimilar((*I)->Pos.x,Pos.x,EPS_L)&&fsimilar((*I)->Pos.z,Pos.z,EPS_L)){ float _dy = (*I)->Pos.y-Pos.y; float _ady= _abs(_dy); if (_dy>=0.f){ if ((_ady<m_Params.fCanUP)&&(_ady<dy_up)) {dy_up=_ady; R_up=*I;} }else{ if ((_ady<m_Params.fCanDOWN)&&(_ady<dy_down)) {dy_down=_ady; R_down=*I;} } } } if (dy_down<=dy_up) R = R_down; else R = R_up; } return R; }
SAINode* ESceneAIMapTool::BuildNode(Fvector& vFrom, Fvector& vAt, bool bIC, bool bSuperIC) // return node's index { // *** Test if we can travel this path SnapXZ (vAt,m_Params.fPatchSize); if (!(bIC||CanTravel(vFrom, vAt))) return 0; // *** set up node SAINode N; BOOL bRes = CreateNode(vAt,N,bIC); if (!bRes&&bIC&&bSuperIC){ Fvector D = {0,1,0}; N.Plane.build(vAt,D); // build plane N.Plane.intersectRayPoint(vAt,D,N.Pos); // "project" position bRes = TRUE; } if (bRes) { //*** check if similar node exists SAINode* old = FindNode(N.Pos); if (!old){ // register xr_new<node AINodeVec* V = HashMap(N.Pos); if (V){ m_Nodes.push_back (xr_new<SAINode>(N)); V->push_back (m_Nodes.back()); return m_Nodes.back(); }else return 0; }else{ // where already was node - return it return old; } }else{ return 0; } }
void ESceneAIMapTool::OnRender(int priority, bool strictB2F) { if (m_Flags.is(flHideNodes) || !ai_map_shown) return; if (1==priority){ if (false==strictB2F){ RCache.set_xform_world(Fidentity); if (OBJCLASS_AIMAP==LTools->CurrentClassID()){ u32 clr = 0xffffc000; Device.SetShader (Device.m_WireShader); DU_impl.DrawSelectionBox (m_AIBBox,&clr); } if (Valid()){ // render nodes Device.SetShader (m_Shader); Device.SetRS (D3DRS_CULLMODE, D3DCULL_NONE); Irect rect; HashRect (Device.m_Camera.GetPosition(),m_VisRadius,rect); u32 vBase; _VertexStream* Stream= &RCache.Vertex; FVF::LIT* pv = (FVF::LIT*)Stream->Lock(block_size,m_RGeom->vb_stride,vBase); u32 cnt = 0; // Device.Statistic.TEST0.Begin(); // Device.Statistic.TEST2.Begin(); for (int x=rect.x1; x<=rect.x2; x++){ for (int z=rect.y1; z<=rect.y2; z++){ AINodeVec* nodes = HashMap(x,z); if (nodes){ const Fvector DUP={0,1,0}; const float st = (m_Params.fPatchSize*0.9f)*0.5f; for (AINodeIt it=nodes->begin(); it!=nodes->end(); it++){ SAINode& N = **it; Fvector v; v.set(N.Pos.x-st,N.Pos.y,N.Pos.z-st); float p_denom = N.Plane.n.dotproduct(DUP); float b = (_abs(p_denom)<EPS_S)?m_Params.fPatchSize:_abs(N.Plane.classify(v) / p_denom); if (Render->ViewBase.testSphere_dirty(N.Pos,_max(b,st))){ u32 clr; if (N.flags.is(SAINode::flSelected))clr = 0xffffffff; else clr = N.flags.is(SAINode::flHLSelected)?0xff909090:0xff606060; int k = 0; if (N.n1) k |= 1<<0; if (N.n2) k |= 1<<1; if (N.n3) k |= 1<<2; if (N.n4) k |= 1<<3; Fvector v; FVF::LIT v1,v2,v3,v4; float tt = 0.01f; v.set(N.Pos.x-st,N.Pos.y,N.Pos.z-st); N.Plane.intersectRayPoint(v,DUP,v1.p); v1.p.mad(v1.p,N.Plane.n,tt); v1.t.set(node_tc[k][0]); v1.color=clr; // minX,minZ v.set(N.Pos.x+st,N.Pos.y,N.Pos.z-st); N.Plane.intersectRayPoint(v,DUP,v2.p); v2.p.mad(v2.p,N.Plane.n,tt); v2.t.set(node_tc[k][1]); v2.color=clr; // maxX,minZ v.set(N.Pos.x+st,N.Pos.y,N.Pos.z+st); N.Plane.intersectRayPoint(v,DUP,v3.p); v3.p.mad(v3.p,N.Plane.n,tt); v3.t.set(node_tc[k][2]); v3.color=clr; // maxX,maxZ v.set(N.Pos.x-st,N.Pos.y,N.Pos.z+st); N.Plane.intersectRayPoint(v,DUP,v4.p); v4.p.mad(v4.p,N.Plane.n,tt); v4.t.set(node_tc[k][3]); v4.color=clr; // minX,maxZ pv->set(v3); pv++; pv->set(v2); pv++; pv->set(v1); pv++; pv->set(v1); pv++; pv->set(v4); pv++; pv->set(v3); pv++; cnt+=6; if (cnt>=block_size-6){ Stream->Unlock (cnt,m_RGeom->vb_stride); Device.DP (D3DPT_TRIANGLELIST,m_RGeom,vBase,cnt/3); pv = (FVF::LIT*)Stream->Lock(block_size,m_RGeom->vb_stride,vBase); cnt = 0; } } } } } } // Device.Statistic.TEST2.End(); // Device.Statistic.TEST0.End(); Stream->Unlock (cnt,m_RGeom->vb_stride); if (cnt) Device.DP (D3DPT_TRIANGLELIST,m_RGeom,vBase,cnt/3); Device.SetRS (D3DRS_CULLMODE, D3DCULL_CCW); } }else{ /* // render snap if (m_Flags.is(flDrawSnapObjects)) for(ObjectIt _F=m_SnapObjects.begin();_F!=m_SnapObjects.end();_F++) if((*_F)->Visible()) ((CSceneObject*)(*_F))->RenderSelection(0x4046B646); */ } } }
#include "MathUtils.h" HashMap MathUtils::cosMap = HashMap(); HashMap MathUtils::sinMap = HashMap(); const glm::mat4 MathUtils::I4 = glm::mat4(); const float MathUtils::PI = glm::pi<float>(); const float MathUtils::twoPI = glm::pi<float>() * 2.0f; float MathUtils::cos(float x) { x = MathUtils::convertTrigInputToStandardRange(x); if (!cosMap.ContainsKey(x)) { //Hasn't been computed before: float cos = cosf(x); cosMap.Put(x, cos); return cos; } return cosMap.Get(x); } float MathUtils::sin(float x) { x = MathUtils::convertTrigInputToStandardRange(x); if (!sinMap.ContainsKey(x)) { //Hasn't been computed before: float sin = sinf(x); sinMap.Put(x, sin); return sin; } return sinMap.Get(x); }