亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? nodetree.cpp

?? 3D游戲引擎 Programming Role-Playing Games with DirectX, 2nd Edition by Jim Adams
?? CPP
字號:
#include "Core_Global.h"
#include "Frustum.h"
#include "NodeTree.h"

cNodeTreeMesh::cNodeTreeMesh()
{
  m_TreeType    = OCTREE;

  m_Graphics    = NULL;

  m_ParentNode  = NULL;

  m_NumGroups   = 0;
  m_Groups      = NULL;

  m_Polygons    = NULL;
  m_NumPolygons = 0;
}

cNodeTreeMesh::~cNodeTreeMesh()
{
  Free();
}

BOOL cNodeTreeMesh::Create(cGraphics *Graphics, cMesh *Mesh, 
                           int TreeType, 
                           float MaxSize, long MaxPolygons)
{
  ID3DXMesh      *LoadMesh;
  unsigned short *IndexPtr;
  unsigned long  *Attributes;
  float           MaxX, MaxY, MaxZ;
  unsigned long   i;

  // Free a prior mesh
  Free();

  // Error checking
  if((m_Graphics = Graphics) == NULL)
    return FALSE;
  if(Mesh == NULL)
    return FALSE;
  if(!Mesh->GetParentMesh()->m_NumMaterials)
    return FALSE;

  // Get mesh info
  m_Mesh        = Mesh->GetParentMesh();
  LoadMesh      = m_Mesh->m_Mesh;
  m_VertexFVF   = LoadMesh->GetFVF();
  m_VertexSize  = D3DXGetFVFVertexSize(m_VertexFVF);
  m_NumPolygons = LoadMesh->GetNumFaces();
  m_MaxPolygons = MaxPolygons;

  // Create the polygon list and groups
  m_Polygons    = new sPolygon[m_NumPolygons]();
  m_NumGroups   = m_Mesh->m_NumMaterials;
  m_Groups      = new sGroup[m_NumGroups]();

  // Lock the index and attribute buffers
  LoadMesh->LockIndexBuffer(D3DLOCK_READONLY, (void**)&IndexPtr);
  LoadMesh->LockAttributeBuffer(D3DLOCK_READONLY, &Attributes);

  // Load polygon information into structures
  for(i=0;i<m_NumPolygons;i++) {
    m_Polygons[i].Vertex0 = *IndexPtr++;
    m_Polygons[i].Vertex1 = *IndexPtr++;
    m_Polygons[i].Vertex2 = *IndexPtr++;

    m_Polygons[i].Group = Attributes[i];
    m_Polygons[i].Timer = 0;

    m_Groups[Attributes[i]].NumPolygons++;
  }

  // Unlock buffers
  LoadMesh->UnlockAttributeBuffer();
  LoadMesh->UnlockIndexBuffer();

  // Build the group vertex index buffers
  for(i=0;i<m_NumGroups;i++) {
    if(m_Groups[i].NumPolygons != 0)
      m_Graphics->GetDeviceCOM()->CreateIndexBuffer(
          m_Groups[i].NumPolygons * 3 * sizeof(unsigned short),
          D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, 
          &m_Groups[i].IndexBuffer, NULL);
  }

  // Get the size of the bounding cube
  MaxX = (float)max(fabs(Mesh->GetParentMesh()->m_Min.x), 
                    fabs(Mesh->GetParentMesh()->m_Max.x));
  MaxY = (float)max(fabs(Mesh->GetParentMesh()->m_Min.y), 
                    fabs(Mesh->GetParentMesh()->m_Max.y));
  MaxZ = (float)max(fabs(Mesh->GetParentMesh()->m_Min.z), 
                    fabs(Mesh->GetParentMesh()->m_Max.z));
  m_Size    = max(MaxX, max(MaxY, MaxZ)) * 2.0f;
  m_MaxSize = MaxSize;

  // Create the parent node
  m_ParentNode = new sNode();

  // Sort polygons into nodes
  LoadMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&m_VertexPtr);
  SortNode(m_ParentNode, 0.0f, 0.0f, 0.0f, m_Size);
  LoadMesh->UnlockVertexBuffer();

  m_Timer = 0; // Reset timer

  return TRUE;
}

BOOL cNodeTreeMesh::Free()
{
  delete m_ParentNode;
  m_ParentNode = NULL;

  m_NumPolygons = 0;
  delete [] m_Polygons;
  m_Polygons = NULL;

  m_NumGroups = 0;
  delete [] m_Groups;
  m_Groups = NULL;

  m_Graphics = NULL;

  return TRUE;
}

void cNodeTreeMesh::SortNode(sNode *Node, 
                             float XPos, float YPos, float ZPos, 
                             float Size)
{
  unsigned long i, Num;
  float         XOff, YOff, ZOff;

  // Error checking
  if(Node == NULL)
    return;

  // Store node coordinates and size
  Node->XPos = XPos;
  Node->YPos = (m_TreeType==QUADTREE)?0.0f:YPos;
  Node->ZPos = ZPos;
  Node->Size = Size;

  // See if there are any polygons in the node
  if(!(Num = CountPolygons(XPos, YPos, ZPos, Size)))
    return;

  // Split node if size > maximum and too many polygons
  if(Size > m_MaxSize && Num > m_MaxPolygons) {
    for(i=0;i<(unsigned long)((m_TreeType==QUADTREE)?4:8);i++) {
      XOff = (((i % 2) < 1) ? -1.0f : 1.0f) * (Size / 4.0f);
      ZOff = (((i % 4) < 2) ? -1.0f : 1.0f) * (Size / 4.0f);
      YOff = (((i % 8) < 4) ? -1.0f : 1.0f) * (Size / 4.0f);

      // See if any polygons in new node bounding box
      if(CountPolygons(XPos+XOff,YPos+YOff,ZPos+ZOff,Size/2.0f)) {
        
        Node->Nodes[i] = new sNode();  // Create new child node

        // Sort the polygons with the new child node
        SortNode(Node->Nodes[i],XPos+XOff,YPos+YOff,ZPos+ZOff,Size/2.0f);
      }
    }

    return;
  }

  // Allocate space for vertex indices
  Node->NumPolygons = Num;
  Node->PolygonList = new unsigned long[Num];

  // Scan through polygon list, storing pointers and assigning them
  Num = 0;
  for(i=0;i<m_NumPolygons;i++) {
    // Add polygon to node list if contained in 3-D space.
    if(IsPolygonContained(&m_Polygons[i],
                          XPos, YPos, ZPos, Size) == TRUE)
      // Store polygon #
      Node->PolygonList[Num++] = i;
  }
}

BOOL cNodeTreeMesh::IsPolygonContained(
                         sPolygon *Polygon,
                         float XPos, float YPos, float ZPos,
                         float Size)
{
  float    XMin, XMax, YMin, YMax, ZMin, ZMax;
  sVertex *Vertex[3];

  // Get the polygon's vertices
  Vertex[0] = (sVertex*)&m_VertexPtr[m_VertexSize * Polygon->Vertex0];
  Vertex[1] = (sVertex*)&m_VertexPtr[m_VertexSize * Polygon->Vertex1];
  Vertex[2] = (sVertex*)&m_VertexPtr[m_VertexSize * Polygon->Vertex2];

  // Check against X axis of specified 3-D space
  XMin = min(Vertex[0]->x, min(Vertex[1]->x, Vertex[2]->x));
  XMax = max(Vertex[0]->x, max(Vertex[1]->x, Vertex[2]->x));
  if(XMax < (XPos - Size / 2.0f))
    return FALSE;
  if(XMin > (XPos + Size / 2.0f))
    return FALSE;

  // Check against Y axis of specified 3-D space (only if octree tree type)
  if(m_TreeType == OCTREE) {
    YMin = min(Vertex[0]->y, min(Vertex[1]->y, Vertex[2]->y));
    YMax = max(Vertex[0]->y, max(Vertex[1]->y, Vertex[2]->y));
    if(YMax < (YPos - Size / 2.0f))
      return FALSE;
    if(YMin > (YPos + Size / 2.0f))
      return FALSE;
  }

  // Check against Z axis of specified 3-D space
  ZMin = min(Vertex[0]->z, min(Vertex[1]->z, Vertex[2]->z));
  ZMax = max(Vertex[0]->z, max(Vertex[1]->z, Vertex[2]->z));
  if(ZMax < (ZPos - Size / 2.0f))
    return FALSE;
  if(ZMin > (ZPos + Size / 2.0f))
    return FALSE;

  return TRUE;
}

unsigned long cNodeTreeMesh::CountPolygons(
                  float XPos, float YPos, float ZPos, float Size)
{
  unsigned long i, Num;
 
   // Return if no polygons to process
  if(!m_NumPolygons)
    return 0;

  // Go through every polygon and keep count of those 
  // contained in the specified 3-D space.
  Num = 0;
  for(i=0;i<m_NumPolygons;i++) {
    if(IsPolygonContained(&m_Polygons[i],
                          XPos,YPos,ZPos,Size) == TRUE)
      Num++;
  }

  return Num;
}

BOOL cNodeTreeMesh::Render(cFrustum *Frustum, float ZDistance)
{
  D3DXMATRIX Matrix;     // Matrix used for calculations
  cFrustum ViewFrustum;  // Local viewing frustum
  IDirect3DVertexBuffer9 *pVB = NULL;
  unsigned long i;

  // Error checking
  if(m_Graphics == NULL || m_ParentNode == NULL || !m_NumPolygons)
    return FALSE;

  // Construct the viewing frustum (if none passed)
  if((m_Frustum = Frustum) == NULL) {
    ViewFrustum.Construct(m_Graphics, ZDistance);
    m_Frustum = &ViewFrustum;
  }

  // Set the world transformation matrix to identity, so that
  // level mesh is rendered around the origin it was designed.
  D3DXMatrixIdentity(&Matrix);
  m_Graphics->GetDeviceCOM()->SetTransform(D3DTS_WORLD, &Matrix);

  // Lock group index buffer
  for(i=0;i<m_NumGroups;i++) {
    if(m_Groups[i].NumPolygons) {
      m_Groups[i].IndexBuffer->Lock(
          0, m_Groups[i].NumPolygons * 3 * sizeof(unsigned short),
          (void**)&m_Groups[i].IndexPtr,0);
    }
    m_Groups[i].NumPolygonsToDraw = 0;
  }

  // Increase frame timer
  m_Timer++;

  // Add polygons to be drawn into group lists
  AddNode(m_ParentNode);
  
  // Get vertex buffer pointer
  m_Mesh->m_Mesh->GetVertexBuffer(&pVB);

  // Set vertex shader and source
  m_Graphics->GetDeviceCOM()->SetStreamSource(0, pVB, 0, m_VertexSize);
  m_Graphics->GetDeviceCOM()->SetFVF(m_VertexFVF);

  // Unlock vertex buffers and draw
  for(i=0;i<m_NumGroups;i++) {
    if(m_Groups[i].NumPolygons)
      m_Groups[i].IndexBuffer->Unlock();

    if(m_Groups[i].NumPolygonsToDraw) {
      m_Graphics->GetDeviceCOM()->SetMaterial(&m_Mesh->m_Materials[i]);
      m_Graphics->GetDeviceCOM()->SetTexture(0, m_Mesh->m_Textures[i]);

      m_Graphics->GetDeviceCOM()->SetIndices(m_Groups[i].IndexBuffer);

      m_Graphics->GetDeviceCOM()->DrawIndexedPrimitive(
                                D3DPT_TRIANGLELIST, 0, 0,
                                m_Mesh->m_Mesh->GetNumVertices(),0,
                                m_Groups[i].NumPolygonsToDraw);
    }
  }
  
  // Release vertex buffer
  if(pVB != NULL)
    pVB->Release();

  return TRUE;
}

void cNodeTreeMesh::AddNode(sNode *Node)
{
  unsigned long i, Group;
  sPolygon     *Polygon;
  short         Num;

  if(Node == NULL)
    return;

  // Perform frustum check based on tree type
  BOOL CompletelyContained = FALSE;
  if(m_TreeType == QUADTREE) {
    if(m_Frustum->CheckRectangle(
           Node->XPos,        0.0f,          Node->ZPos, 
           Node->Size / 2.0f, m_Size / 2.0f, Node->Size / 2.0f,
           &CompletelyContained) == FALSE)
      return;
  } else {
    if(m_Frustum->CheckRectangle(
           Node->XPos,        Node->YPos,        Node->ZPos, 
           Node->Size / 2.0f, Node->Size / 2.0f, Node->Size / 2.0f,
           &CompletelyContained) == FALSE)
      return;
  }

  if(CompletelyContained == FALSE) {

    // Scan other nodes
    Num = 0;
    for(i=0;i<(unsigned long)((m_TreeType==QUADTREE)?4:8);i++) {
      if(Node->Nodes[i] != NULL) {
        Num++;
        AddNode(Node->Nodes[i]);
      }
    }


    // Don't need to go on if there was other nodes
    if(Num)
      return;
  }

  // Add contained polygons (if any)
  if(Node->NumPolygons != 0) {

    for(i=0;i<Node->NumPolygons;i++) {

      // Get pointer to polygon
      Polygon = &m_Polygons[Node->PolygonList[i]];

      // Only draw if not done already this frame
      if(Polygon->Timer != m_Timer) {
      
        // Set polygon as processed this frame
        Polygon->Timer = m_Timer;

        // Get material group of polygon
        Group = Polygon->Group;

        // Make sure group is okay and material is not transparent
        if(Group < m_NumGroups && m_Mesh->m_Materials[Group].Diffuse.a != 0.0f) {

          // Copy indices into index buffer
          *m_Groups[Group].IndexPtr++ = Polygon->Vertex0;
          *m_Groups[Group].IndexPtr++ = Polygon->Vertex1;
          *m_Groups[Group].IndexPtr++ = Polygon->Vertex2;
      
          // Increase count of polygons to draw in group
          m_Groups[Group].NumPolygonsToDraw++;
        }
      }
    }
  }
}

float cNodeTreeMesh::GetClosestHeight(float XPos, float YPos, float ZPos)
{
  float YAbove, YBelow;

  YAbove = GetHeightAbove(XPos, YPos, ZPos);
  YBelow = GetHeightBelow(XPos, YPos, ZPos);
  if(fabs(YAbove-YPos) < fabs(YBelow-YPos))
    return YAbove;
  return YBelow;
}

float cNodeTreeMesh::GetHeightBelow(float XPos, float YPos, float ZPos)
{
  BOOL  Hit;
  float u, v, Dist;
  DWORD FaceIndex;

  D3DXIntersect(m_Mesh->m_Mesh,
                &D3DXVECTOR3(XPos,YPos,ZPos),
                &D3DXVECTOR3(0.0f, -1.0f, 0.0f),
                &Hit, &FaceIndex, &u, &v, &Dist, NULL, NULL);
  if(Hit == TRUE)
    return YPos-Dist;
  return YPos;
}

float cNodeTreeMesh::GetHeightAbove(float XPos, float YPos, float ZPos)
{ 
  BOOL  Hit;
  float u, v, Dist;
  DWORD FaceIndex;

  D3DXIntersect(m_Mesh->m_Mesh,
                &D3DXVECTOR3(XPos,YPos,ZPos),
                &D3DXVECTOR3(0.0f, 1.0f, 0.0f),
                &Hit, &FaceIndex, &u, &v, &Dist, NULL, NULL);
  if(Hit == TRUE)
    return YPos+Dist;
  return YPos;
}

BOOL cNodeTreeMesh::CheckIntersect(float XStart, float YStart, float ZStart,
                                   float XEnd,   float YEnd,   float ZEnd,
                                   float *Length)
{
  BOOL  Hit;
  float u, v, Dist;
  float XDiff, YDiff, ZDiff, Size;
  DWORD FaceIndex;
  D3DXVECTOR3 vecDir;

  XDiff = XEnd - XStart;
  YDiff = YEnd - YStart;
  ZDiff = ZEnd - ZStart;

  D3DXVec3Normalize(&vecDir, &D3DXVECTOR3(XDiff, YDiff, ZDiff));
  D3DXIntersect(m_Mesh->m_Mesh,
                &D3DXVECTOR3(XStart,YStart,ZStart), &vecDir,
                &Hit, &FaceIndex, &u, &v, &Dist, NULL, NULL);

  if(Hit == TRUE) {
    Size = (float)sqrt(XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff);
    if(Dist > Size)
      Hit = FALSE;
    else {
      if(Length != NULL)
        *Length = Dist;
    }
  }

  return Hit;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
在线播放欧美女士性生活| 91成人国产精品| 欧美高清你懂得| 中文字幕一区二区三区乱码在线| 日本va欧美va精品发布| 日本久久电影网| 国产精品美女久久久久aⅴ| 久久精品国产99国产精品| 欧洲生活片亚洲生活在线观看| 国产精品网站在线| 紧缚奴在线一区二区三区| 欧美四级电影网| 亚洲欧美偷拍三级| 粉嫩13p一区二区三区| 日韩亚洲欧美高清| 亚洲大片精品永久免费| 99在线精品观看| 欧美国产精品专区| 国产乱理伦片在线观看夜一区 | 日本欧美韩国一区三区| 91丨porny丨在线| 国产日韩精品一区二区三区在线| 狠狠色狠狠色综合系列| 欧美一级理论性理论a| 天天综合色天天综合色h| 日本久久精品电影| 一区二区三区资源| 色综合咪咪久久| 亚洲色图欧美激情| 一本久道久久综合中文字幕| 国产精品国产三级国产三级人妇| 成人免费高清视频| 国产精品热久久久久夜色精品三区 | 欧美一区二区三区人| 亚洲成人免费看| 欧美军同video69gay| 亚洲成人av资源| 91精品欧美福利在线观看| 日韩av网站在线观看| 欧美一区二区三区在线视频| 免费成人你懂的| 精品国产成人在线影院| 国产精品自拍一区| 国产三级欧美三级| 成人激情校园春色| 中文字幕一区二| 色悠悠久久综合| 亚洲成av人片在线观看| 91精品国产综合久久精品性色| 日本美女一区二区| 欧美电影免费观看高清完整版| 精品一区二区三区久久| 久久综合999| 成人动漫视频在线| 亚洲精品国产一区二区精华液| 欧美在线三级电影| 婷婷中文字幕一区三区| 精品少妇一区二区三区视频免付费| 国产一区在线观看视频| 中文字幕乱码日本亚洲一区二区| www.成人网.com| 亚洲日本青草视频在线怡红院| 在线观看日韩高清av| 婷婷亚洲久悠悠色悠在线播放 | 在线观看亚洲精品| 婷婷国产在线综合| 久久综合色综合88| 99精品视频中文字幕| 亚洲成人在线免费| 精品三级在线观看| av成人老司机| 午夜在线成人av| 久久日一线二线三线suv| 成人av电影在线网| 亚洲午夜免费视频| 欧美不卡视频一区| 99在线热播精品免费| 午夜精品久久久久久久久| 欧美精品一区二区蜜臀亚洲| 99久久精品国产一区二区三区| 婷婷开心激情综合| 国产亚洲欧美在线| 91国偷自产一区二区开放时间 | 蜜桃视频第一区免费观看| 国产视频一区在线观看| 欧美视频一区二区在线观看| 精品在线免费观看| 亚洲免费在线视频| 精品欧美久久久| 日本韩国欧美一区二区三区| 蜜臀国产一区二区三区在线播放| 国产精品久久久久久久蜜臀| 51精品秘密在线观看| 99久久er热在这里只有精品66| 日精品一区二区三区| 国产精品你懂的在线欣赏| 欧美一卡在线观看| 91免费版pro下载短视频| 久久er99精品| 一区二区三区**美女毛片| 久久这里只有精品6| 欧美日韩免费不卡视频一区二区三区| 国产精品综合在线视频| 视频一区在线播放| 综合久久久久久| 欧美成人video| 在线观看日韩高清av| 国产91精品精华液一区二区三区| 日本系列欧美系列| 自拍偷拍欧美激情| 久久久精品天堂| 91精品国产丝袜白色高跟鞋| 91在线一区二区| 国产麻豆91精品| 日韩激情一区二区| 樱花影视一区二区| 欧美国产一区在线| 欧美电视剧在线观看完整版| 在线观看亚洲成人| www.日韩av| 国产精品一区二区免费不卡| 亚洲va天堂va国产va久| 国产精品久久久久久久午夜片| 日韩精品一区二区三区四区| 欧美日韩美女一区二区| 色婷婷av一区二区| 成人动漫一区二区在线| 九九国产精品视频| 青青草精品视频| 午夜精品一区在线观看| 亚洲精品日韩综合观看成人91| 欧美国产精品中文字幕| 久久久久久久综合日本| 欧美大片在线观看一区二区| 欧美巨大另类极品videosbest| 色综合视频在线观看| 成人国产精品免费观看视频| 国产一区二区三区| 久久精品99国产精品日本| 日韩av一二三| 天堂一区二区在线免费观看| 亚洲一区二区三区自拍| 亚洲精品日产精品乱码不卡| 国产精品久久久爽爽爽麻豆色哟哟 | 99re成人精品视频| 成人影视亚洲图片在线| 成人免费毛片嘿嘿连载视频| 国产精品一二三四| 国产在线不卡一区| 国产专区欧美精品| 韩国av一区二区三区四区| 久久精品国产亚洲高清剧情介绍 | 理论片日本一区| 老司机午夜精品| 蜜臀91精品一区二区三区 | 亚洲成a人v欧美综合天堂| 亚洲欧美激情插| 一区二区三区四区精品在线视频 | 国产精品福利影院| 亚洲色图制服丝袜| 亚洲视频网在线直播| 亚洲欧美精品午睡沙发| 一区二区高清在线| 天堂精品中文字幕在线| 免费黄网站欧美| 狠狠色丁香久久婷婷综| 国产一区二三区| 国产成人综合在线观看| 国产成人aaa| 99久久精品费精品国产一区二区| 91视频.com| 欧美视频精品在线观看| 3atv一区二区三区| 日韩欧美黄色影院| 国产日韩欧美精品一区| 亚洲女女做受ⅹxx高潮| 亚洲二区在线观看| 秋霞国产午夜精品免费视频| 狠狠色丁香久久婷婷综合_中| 国产aⅴ综合色| 成人av免费在线播放| 欧美做爰猛烈大尺度电影无法无天| 欧美日韩一二区| 精品国产亚洲在线| 国产精品国产三级国产a| 亚洲一区二区欧美日韩| 免费成人av在线| 成人污污视频在线观看| 91国偷自产一区二区使用方法| 91精品午夜视频| 国产婷婷色一区二区三区在线| 一区在线观看视频| 午夜伦欧美伦电影理论片| 久草这里只有精品视频| 97超碰欧美中文字幕| 91.xcao| 欧美国产一区在线| 午夜久久福利影院| 亚洲精品在线免费观看视频| caoporen国产精品视频|