BVB Source Codes

CRYENGINE Show RoadRenderNode.cpp Source code

Return Download CRYENGINE: download RoadRenderNode.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4.  
  5. #include "3dEngine.h"
  6. #include "PolygonClipContext.h"
  7. #include "RoadRenderNode.h"
  8. #include "terrain.h"
  9. #include "ObjMan.h"
  10. #include "MeshCompiler/MeshCompiler.h"
  11.  
  12. #include "CryCore/TypeInfo_impl.h"
  13.  
  14. const float fRoadAreaZRange = 2.5f;
  15. const float fRoadTerrainZOffset = 0.06f;
  16.  
  17. // tmp buffers used during road mesh creation
  18. PodArray<Vec3> CRoadRenderNode::s_tempVertexPositions;
  19. PodArray<vtx_idx> CRoadRenderNode::s_tempIndices;
  20. PodArray<SPipTangents> CRoadRenderNode::s_tempTangents;
  21. PodArray<SVF_P3F_C4B_T2S> CRoadRenderNode::s_tempVertices;
  22. CPolygonClipContext CRoadRenderNode::s_tmpClipContext;
  23. ILINE Vec3 max(const Vec3& v0, const Vec3& v1) { return Vec3(max(v0.x, v1.x), max(v0.y, v1.y), max(v0.z, v1.z)); }
  24. ILINE Vec3 min(const Vec3& v0, const Vec3& v1) { return Vec3(min(v0.x, v1.x), min(v0.y, v1.y), min(v0.z, v1.z)); }
  25.  
  26. STRUCT_INFO_BEGIN(CRoadRenderNode::SData)
  27. STRUCT_VAR_INFO(arrTexCoors, TYPE_ARRAY(2, TYPE_INFO(float)))
  28. STRUCT_VAR_INFO(arrTexCoorsGlobal, TYPE_ARRAY(2, TYPE_INFO(float)))
  29.  
  30. STRUCT_VAR_INFO(worldSpaceBBox, TYPE_INFO(AABB))
  31.  
  32. STRUCT_VAR_INFO(numVertices, TYPE_INFO(uint32))
  33. STRUCT_VAR_INFO(numIndices, TYPE_INFO(uint32))
  34. STRUCT_VAR_INFO(numTangents, TYPE_INFO(uint32))
  35.  
  36. STRUCT_VAR_INFO(physicsGeometryCount, TYPE_INFO(uint32))
  37.  
  38. STRUCT_VAR_INFO(sourceVertexCount, TYPE_INFO(uint32))
  39. STRUCT_INFO_END(CRoadRenderNode::SData)
  40.  
  41. STRUCT_INFO_BEGIN(CRoadRenderNode::SPhysicsGeometryParams)
  42. STRUCT_VAR_INFO(size, TYPE_INFO(Vec3))
  43. STRUCT_VAR_INFO(pos, TYPE_INFO(Vec3))
  44. STRUCT_VAR_INFO(q, TYPE_INFO(Quat))
  45. STRUCT_INFO_END(CRoadRenderNode::SPhysicsGeometryParams)
  46.  
  47. CRoadRenderNode::CRoadRenderNode()
  48.         : m_bRebuildFull(false)
  49. {
  50.         m_pRenderMesh = NULL;
  51.         m_pMaterial = NULL;
  52.         m_serializedData.arrTexCoors[0] = m_serializedData.arrTexCoorsGlobal[0] = 0;
  53.         m_serializedData.arrTexCoors[1] = m_serializedData.arrTexCoorsGlobal[1] = 1;
  54.         m_pPhysEnt = NULL;
  55.         m_sortPrio = 0;
  56.         m_nLayerId = 0;
  57.         m_bIgnoreTerrainHoles = false;
  58.         m_bPhysicalize = false;
  59.  
  60.         GetInstCount(GetRenderNodeType())++;
  61. }
  62.  
  63. CRoadRenderNode::~CRoadRenderNode()
  64. {
  65.         Dephysicalize();
  66.         m_pRenderMesh = NULL;
  67.         Get3DEngine()->FreeRenderNodeState(this);
  68.  
  69.         Get3DEngine()->m_lstRoadRenderNodesForUpdate.Delete(this);
  70.  
  71.         GetInstCount(GetRenderNodeType())--;
  72. }
  73.  
  74. // Sets vertices, texture coordinates and updates the bbox.
  75. // Only called when actually modifying the road, should never be called in Launcher normally.
  76. void CRoadRenderNode::SetVertices(const Vec3* pVertsAll, int nVertsNumAll,
  77.                                   float fTexCoordBegin, float fTexCoordEnd,
  78.                                   float fTexCoordBeginGlobal, float fTexCoordEndGlobal)
  79. {
  80.         if (pVertsAll != m_arrVerts.GetElements())
  81.         {
  82.                 m_arrVerts.Clear();
  83.                 m_arrVerts.AddList((Vec3*)pVertsAll, nVertsNumAll);
  84.  
  85.                 // work around for cracks between road segments
  86.                 if (m_arrVerts.Count() >= 4)
  87.                 {
  88.                         if (fTexCoordBegin != fTexCoordBeginGlobal)
  89.                         {
  90.                                 Vec3 m0 = (m_arrVerts[0] + m_arrVerts[1]) * .5f;
  91.                                 Vec3 m1 = (m_arrVerts[2] + m_arrVerts[3]) * .5f;
  92.                                 Vec3 vDir = (m0 - m1).GetNormalized() * 0.01f;
  93.                                 m_arrVerts[0] += vDir;
  94.                                 m_arrVerts[1] += vDir;
  95.                         }
  96.  
  97.                         if (fTexCoordEnd != fTexCoordEndGlobal)
  98.                         {
  99.                                 int n = m_arrVerts.Count();
  100.                                 Vec3 m0 = (m_arrVerts[n - 1] + m_arrVerts[n - 2]) * .5f;
  101.                                 Vec3 m1 = (m_arrVerts[n - 3] + m_arrVerts[n - 4]) * .5f;
  102.                                 Vec3 vDir = (m0 - m1).GetNormalized() * 0.01f;
  103.                                 m_arrVerts[n - 1] += vDir;
  104.                                 m_arrVerts[n - 2] += vDir;
  105.                         }
  106.                 }
  107.         }
  108.  
  109.         // Adjust uv coords to smaller range to avoid f16 precision errors.
  110.         // Need to adjust global ranges too to keep relative fades at ends of spline
  111.         const float fNodeStart = static_cast<float>(static_cast<int>(fTexCoordBegin));
  112.         const float fNodeOffset = fTexCoordBegin - fNodeStart;
  113.  
  114.         m_serializedData.arrTexCoors[0] = fNodeOffset;
  115.         m_serializedData.arrTexCoors[1] = fNodeOffset + (fTexCoordEnd - fTexCoordBegin);
  116.  
  117.         m_serializedData.arrTexCoorsGlobal[0] = fTexCoordBeginGlobal - fNodeStart;
  118.         m_serializedData.arrTexCoorsGlobal[1] = fTexCoordBeginGlobal + (fTexCoordEndGlobal - fTexCoordBeginGlobal) - fNodeStart;
  119.  
  120.         m_serializedData.worldSpaceBBox.Reset();
  121.         for (int i = 0; i < nVertsNumAll; i++)
  122.                 m_serializedData.worldSpaceBBox.Add(m_arrVerts[i]);
  123.  
  124.         m_serializedData.worldSpaceBBox.min -= Vec3(0.1f, 0.1f, fRoadAreaZRange);
  125.         m_serializedData.worldSpaceBBox.max += Vec3(0.1f, 0.1f, fRoadAreaZRange);
  126.  
  127.         // Query rebuild, results in CRoadRenderNode::Compile being called
  128.         // In this case the road vertices were changed, schedule a full rebuild.
  129.         ScheduleRebuild(true);
  130. }
  131.  
  132. void CRoadRenderNode::Compile() PREFAST_SUPPRESS_WARNING(6262) //function uses > 32k stack space
  133. {
  134.         LOADING_TIME_PROFILE_SECTION;
  135.  
  136.         // free old object and mesh
  137.         m_pRenderMesh = NULL;
  138.  
  139.         // Make sure to dephysicalize first
  140.         Dephysicalize();
  141.  
  142.         Vec3 segmentOffset(0, 0, 0);
  143.         if (Get3DEngine()->m_pSegmentsManager)
  144.         {
  145.                 segmentOffset = GetTerrain()->GetSegmentOrigin(m_nSID);
  146.         }
  147.  
  148.         // The process of generating the render mesh is very slow, only perform if the road changed!
  149.         if (m_bRebuildFull)
  150.         {
  151.                 Plane arrPlanes[6];
  152.                 float arrTexCoors[2];
  153.  
  154.                 int nVertsNumAll = m_arrVerts.Count();
  155.  
  156.                 assert(!(nVertsNumAll & 1));
  157.  
  158.                 if (nVertsNumAll < 4)
  159.                         return;
  160.  
  161.                 m_serializedData.worldSpaceBBox.Reset();
  162.                 for (int i = 0; i < nVertsNumAll; i++)
  163.                 {
  164.                         Vec3 vTmp(m_arrVerts[i].x, m_arrVerts[i].y, Get3DEngine()->GetTerrainElevation(m_arrVerts[i].x, m_arrVerts[i].y, m_nSID) + fRoadTerrainZOffset);
  165.                         m_serializedData.worldSpaceBBox.Add(vTmp);
  166.                 }
  167.  
  168.                 // prepare arrays for final mesh
  169.                 const int nMaxVerticesToMerge = 1024 * 32; // limit memory usage
  170.                 m_dynamicData.vertices.PreAllocate(nMaxVerticesToMerge, 0);
  171.                 m_dynamicData.indices.PreAllocate(nMaxVerticesToMerge * 6, 0);
  172.                 m_dynamicData.tangents.PreAllocate(nMaxVerticesToMerge, 0);
  173.  
  174.                 float fChunksNum = (float)((nVertsNumAll - 2) / 2);
  175.                 float fTexStep = (m_serializedData.arrTexCoors[1] - m_serializedData.arrTexCoors[0]) / fChunksNum;
  176.  
  177.                 // for every trapezoid
  178.                 for (int nVertId = 0; nVertId <= nVertsNumAll - 4; nVertId += 2)
  179.                 {
  180.                         const Vec3* pVerts = &m_arrVerts[nVertId];
  181.  
  182.                         if (pVerts[0] == pVerts[1] ||
  183.                             pVerts[1] == pVerts[2] ||
  184.                             pVerts[2] == pVerts[3] ||
  185.                             pVerts[3] == pVerts[0])
  186.                                 continue;
  187.  
  188.                         // get texture coordinates range
  189.                         arrTexCoors[0] = m_serializedData.arrTexCoors[0] + fTexStep * (nVertId / 2);
  190.                         arrTexCoors[1] = m_serializedData.arrTexCoors[0] + fTexStep * (nVertId / 2 + 1);
  191.  
  192.                         GetClipPlanes(&arrPlanes[0], 4, nVertId);
  193.  
  194.                         // make trapezoid 2d bbox
  195.                         AABB WSBBox;
  196.                         WSBBox.Reset();
  197.                         for (int i = 0; i < 4; i++)
  198.                         {
  199.                                 Vec3 vTmp(pVerts[i].x, pVerts[i].y, pVerts[i].z);
  200.                                 WSBBox.Add(vTmp);
  201.                         }
  202.  
  203.                         // make vert array
  204.                         int nUnitSize = GetTerrain()->GetHeightMapUnitSize();
  205. #ifndef SEG_WORLD
  206.                         int x1 = int(WSBBox.min.x) / nUnitSize * nUnitSize;
  207.                         int x2 = int(WSBBox.max.x) / nUnitSize * nUnitSize + nUnitSize;
  208.                         int y1 = int(WSBBox.min.y) / nUnitSize * nUnitSize;
  209.                         int y2 = int(WSBBox.max.y) / nUnitSize * nUnitSize + nUnitSize;
  210. #else
  211.                         int x1 = int(WSBBox.min.x + segmentOffset.x) / nUnitSize * nUnitSize;
  212.                         int x2 = int(WSBBox.max.x + segmentOffset.x) / nUnitSize * nUnitSize + nUnitSize;
  213.                         int y1 = int(WSBBox.min.y + segmentOffset.y) / nUnitSize * nUnitSize;
  214.                         int y2 = int(WSBBox.max.y + segmentOffset.y) / nUnitSize * nUnitSize + nUnitSize;
  215.                         x1 -= (int)segmentOffset.x;
  216.                         x2 -= (int)segmentOffset.x;
  217.                         y1 -= (int)segmentOffset.y;
  218.                         y2 -= (int)segmentOffset.y;
  219. #endif
  220.  
  221.                         // make arrays of verts and indices used in trapezoid area
  222.                         s_tempVertexPositions.Clear();
  223.                         s_tempIndices.Clear();
  224.  
  225.                         for (int x = x1; x <= x2; x += nUnitSize)
  226.                         {
  227.                                 for (int y = y1; y <= y2; y += nUnitSize)
  228.                                 {
  229.                                         s_tempVertexPositions.Add(Vec3((float)x, (float)y, GetTerrain()->GetZ(x, y, m_nSID, true)));
  230.                                 }
  231.                         }
  232.  
  233.                         // make indices
  234.                         int dx = (x2 - x1) / nUnitSize;
  235.                         int dy = (y2 - y1) / nUnitSize;
  236.  
  237.                         for (int x = 0; x < dx; x++)
  238.                         {
  239.                                 for (int y = 0; y < dy; y++)
  240.                                 {
  241.                                         int nIdx0 = (x * (dy + 1) + y);
  242.                                         int nIdx1 = (x * (dy + 1) + y + (dy + 1));
  243.                                         int nIdx2 = (x * (dy + 1) + y + 1);
  244.                                         int nIdx3 = (x * (dy + 1) + y + 1 + (dy + 1));
  245.  
  246.                                         int X_in_meters = x1 + x * nUnitSize;
  247.                                         int Y_in_meters = y1 + y * nUnitSize;
  248.  
  249.                                         CTerrain* pTerrain = GetTerrain();
  250.  
  251.                                         if (m_bIgnoreTerrainHoles || (pTerrain && !pTerrain->GetHole(X_in_meters, Y_in_meters, m_nSID)))
  252.                                         {
  253.                                                 if (pTerrain && pTerrain->IsMeshQuadFlipped(X_in_meters, Y_in_meters, nUnitSize, m_nSID))
  254.                                                 {
  255.                                                         s_tempIndices.Add(nIdx0);
  256.                                                         s_tempIndices.Add(nIdx1);
  257.                                                         s_tempIndices.Add(nIdx3);
  258.  
  259.                                                         s_tempIndices.Add(nIdx0);
  260.                                                         s_tempIndices.Add(nIdx3);
  261.                                                         s_tempIndices.Add(nIdx2);
  262.                                                 }
  263.                                                 else
  264.                                                 {
  265.                                                         s_tempIndices.Add(nIdx0);
  266.                                                         s_tempIndices.Add(nIdx1);
  267.                                                         s_tempIndices.Add(nIdx2);
  268.  
  269.                                                         s_tempIndices.Add(nIdx1);
  270.                                                         s_tempIndices.Add(nIdx3);
  271.                                                         s_tempIndices.Add(nIdx2);
  272.                                                 }
  273.                                         }
  274.                                 }
  275.                         }
  276.  
  277.                         // clip triangles
  278.                         int nOrigCount = s_tempIndices.Count();
  279.                         for (int i = 0; i < nOrigCount; i += 3)
  280.                         {
  281.                                 if (ClipTriangle(s_tempVertexPositions, s_tempIndices, i, arrPlanes))
  282.                                 {
  283.                                         i -= 3;
  284.                                         nOrigCount -= 3;
  285.                                 }
  286.                         }
  287.  
  288.                         if (s_tempIndices.Count() < 3 || s_tempVertexPositions.Count() < 3)
  289.                                 continue;
  290.  
  291.                         if (m_bPhysicalize)
  292.                         {
  293.                                 Vec3 axis = (pVerts[2] + pVerts[3] - pVerts[0] - pVerts[1]).normalized(), n = (pVerts[1] - pVerts[0] ^ pVerts[2] - pVerts[0]) + (pVerts[2] - pVerts[3] ^ pVerts[2] - pVerts[3]);
  294.                                 (n -= axis * (n * axis)).normalize();
  295.  
  296.                                 SPhysicsGeometryParams physParams;
  297.  
  298.                                 Vec3 bbox[2];
  299.                                 bbox[0] = VMAX;
  300.                                 bbox[1] = VMIN;
  301.  
  302.                                 physParams.q = Quat(Matrix33::CreateFromVectors(axis, n ^ axis, n));
  303.  
  304.                                 for (int j = 0; j < s_tempIndices.Count(); j++)
  305.                                 {
  306.                                         Vec3 ptloc = s_tempVertexPositions[s_tempIndices[j]] * physParams.q;
  307.                                         bbox[0] = min(bbox[0], ptloc);
  308.                                         bbox[1] = max(bbox[1], ptloc);
  309.                                 }
  310.  
  311.                                 physParams.pos = physParams.q * (bbox[1] + bbox[0]) * 0.5f;
  312.                                 physParams.size = (bbox[1] - bbox[0]) * 0.5f;
  313.  
  314.                                 m_dynamicData.physicsGeometry.Add(physParams);
  315.                         }
  316.  
  317.                         // allocate tangent array
  318.                         s_tempTangents.Clear();
  319.                         s_tempTangents.PreAllocate(s_tempVertexPositions.Count(), s_tempVertexPositions.Count());
  320.  
  321.                         int nStep = CTerrain::GetHeightMapUnitSize();
  322.  
  323.                         Vec3 vWSBoxCenter = m_serializedData.worldSpaceBBox.GetCenter(); //vWSBoxCenter.z=0;
  324.  
  325.                         // make real vertex data
  326.                         s_tempVertices.Clear();
  327.                         for (int i = 0; i < s_tempVertexPositions.Count(); i++)
  328.                         {
  329.                                 SVF_P3F_C4B_T2S tmp;
  330.  
  331.                                 Vec3 vWSPos = s_tempVertexPositions[i];
  332.  
  333.                                 tmp.xyz = (vWSPos - vWSBoxCenter);
  334.  
  335.                                 // do texgen
  336.                                 float d0 = arrPlanes[0].DistFromPlane(vWSPos);
  337.                                 float d1 = arrPlanes[1].DistFromPlane(vWSPos);
  338.                                 float d2 = arrPlanes[2].DistFromPlane(vWSPos);
  339.                                 float d3 = arrPlanes[3].DistFromPlane(vWSPos);
  340.  
  341.                                 float t = fabsf(d0 + d1) < FLT_EPSILON ? 0.0f : d0 / (d0 + d1);
  342.                                 tmp.st = Vec2f16((1 - t) * fabs(arrTexCoors[0]) + t * fabs(arrTexCoors[1]), fabsf(d2 + d3) < FLT_EPSILON ? 0.0f : d2 / (d2 + d3));
  343.  
  344.                                 // calculate alpha value
  345.                                 float fAlpha = 1.f;
  346.                                 if (fabs(arrTexCoors[0] - m_serializedData.arrTexCoorsGlobal[0]) < 0.01f)
  347.                                         fAlpha = CLAMP(t, 0, 1.f);
  348.                                 else if (fabs(arrTexCoors[1] - m_serializedData.arrTexCoorsGlobal[1]) < 0.01f)
  349.                                         fAlpha = CLAMP(1.f - t, 0, 1.f);
  350.  
  351.                                 tmp.color.bcolor[0] = 255;
  352.                                 tmp.color.bcolor[1] = 255;
  353.                                 tmp.color.bcolor[2] = 255;
  354.                                 tmp.color.bcolor[3] = uint8(255.f * fAlpha);
  355.                                 SwapEndian(tmp.color.dcolor, eLittleEndian);
  356.  
  357.                                 s_tempVertices.Add(tmp);
  358.  
  359.                                 Vec3 vNormal = GetTerrain()->GetTerrainSurfaceNormal(vWSPos, 0.25f, m_nSID);
  360.  
  361.                                 Vec3 vBiTang = pVerts[1] - pVerts[0];
  362.                                 vBiTang.Normalize();
  363.  
  364.                                 Vec3 vTang = pVerts[2] - pVerts[0];
  365.                                 vTang.Normalize();
  366.  
  367.                                 vBiTang = -vNormal.Cross(vTang);
  368.                                 vTang = vNormal.Cross(vBiTang);
  369.  
  370.                                 s_tempTangents[i] = SPipTangents(vTang, vBiTang, -1);
  371.                         }
  372.  
  373.                         // shift indices
  374.                         for (int i = 0; i < s_tempIndices.Count(); i++)
  375.                                 s_tempIndices[i] += m_dynamicData.vertices.size();
  376.  
  377.                         if (m_dynamicData.vertices.size() + s_tempVertices.Count() > nMaxVerticesToMerge)
  378.                         {
  379.                                 Warning("Road object is too big, has to be split into several smaller parts (pos=%d,%d,%d)", (int)m_serializedData.worldSpaceBBox.GetCenter().x, (int)m_serializedData.worldSpaceBBox.GetCenter().y, (int)m_serializedData.worldSpaceBBox.GetCenter().z);
  380.                                 return;
  381.                         }
  382.  
  383.                         m_dynamicData.indices.AddList(s_tempIndices);
  384.                         m_dynamicData.vertices.AddList(s_tempVertices);
  385.                         m_dynamicData.tangents.AddList(s_tempTangents);
  386.                 }
  387.  
  388.                 PodArray<SPipNormal> dummyNormals;
  389.  
  390.                 mesh_compiler::CMeshCompiler meshCompiler;
  391.                 meshCompiler.WeldPos_VF_P3X(m_dynamicData.vertices, m_dynamicData.tangents, dummyNormals, m_dynamicData.indices, VEC_EPSILON, GetBBox());
  392.         }
  393.  
  394.         // make render mesh
  395.         if (m_dynamicData.indices.Count() && GetRenderer())
  396.         {
  397.                 m_pRenderMesh = GetRenderer()->CreateRenderMeshInitialized(
  398.                   m_dynamicData.vertices.GetElements(), m_dynamicData.vertices.Count(), eVF_P3F_C4B_T2S,
  399.                   m_dynamicData.indices.GetElements(), m_dynamicData.indices.Count(), prtTriangleList,
  400.                   "RoadRenderNode", GetName(), eRMT_Static, 1, 0, NULL, NULL, false, true, m_dynamicData.tangents.GetElements());
  401.  
  402.                 // Calculate the texel area density
  403.                 float texelAreaDensity = 1.0f;
  404.  
  405.                 const size_t indexCount = m_dynamicData.indices.size();
  406.                 const size_t vertexCount = m_dynamicData.vertices.size();
  407.  
  408.                 if ((indexCount > 0) && (vertexCount > 0))
  409.                 {
  410.                         float posArea;
  411.                         float texArea;
  412.                         const char* errorText = "";
  413.  
  414.                         const bool ok = CMeshHelpers::ComputeTexMappingAreas(
  415.                           indexCount, &m_dynamicData.indices[0],
  416.                           vertexCount,
  417.                           &m_dynamicData.vertices[0].xyz, sizeof(m_dynamicData.vertices[0]),
  418.                           &m_dynamicData.vertices[0].st, sizeof(m_dynamicData.vertices[0]),
  419.                           posArea, texArea, errorText);
  420.  
  421.                         if (ok)
  422.                         {
  423.                                 texelAreaDensity = texArea / posArea;
  424.                         }
  425.                         else
  426.                         {
  427.                                 gEnv->pLog->LogError("Failed to compute texture mapping density for mesh '%s': %s", GetName(), errorText);
  428.                         }
  429.                 }
  430.  
  431.                 m_pRenderMesh->SetChunk((m_pMaterial != NULL) ? (IMaterial*)m_pMaterial : gEnv->p3DEngine->GetMaterialManager()->GetDefaultMaterial(),
  432.                                         0, m_dynamicData.vertices.Count(), 0, m_dynamicData.indices.Count(), texelAreaDensity);
  433.                 m_serializedData.worldSpaceBBox.Move(segmentOffset);
  434.                 Vec3 vWSBoxCenter = m_serializedData.worldSpaceBBox.GetCenter(); //vWSBoxCenter.z=0;
  435.                 AABB OSBBox(m_serializedData.worldSpaceBBox.min - vWSBoxCenter, m_serializedData.worldSpaceBBox.max - vWSBoxCenter);
  436.                 m_pRenderMesh->SetBBox(OSBBox.min, OSBBox.max);
  437.  
  438.                 if (m_bPhysicalize)
  439.                 {
  440.                         LOADING_TIME_PROFILE_SECTION_NAMED("RoadPhysicalization");
  441.  
  442.                         IGeomManager* pGeoman = GetPhysicalWorld()->GetGeomManager();
  443.                         primitives::box abox;
  444.                         pe_geomparams gp;
  445.                         int matid = 0;
  446.                         abox.center.zero();
  447.                         abox.Basis.SetIdentity();
  448.                         gp.flags = geom_mat_substitutor;
  449.                         pe_params_flags pf;
  450.                         pf.flagsAND = ~pef_traceable;
  451.                         pf.flagsOR = pef_parts_traceable;
  452.                         m_pPhysEnt = GetPhysicalWorld()->CreatePhysicalEntity(PE_STATIC, &pf);
  453.  
  454.                         if (m_pMaterial && m_pPhysEnt)
  455.                         {
  456.                                 LOADING_TIME_PROFILE_SECTION_NAMED("RoadPhysicalizationParts");
  457.  
  458.                                 ISurfaceType* psf;
  459.                                 if ((psf = m_pMaterial->GetSurfaceType()) || m_pMaterial->GetSubMtl(0) && (psf = m_pMaterial->GetSubMtl(0)->GetSurfaceType()))
  460.                                         matid = psf->GetId();
  461.  
  462.                                 phys_geometry* pPhysGeom;
  463.  
  464.                                 for (int i = 0, numParts = m_dynamicData.physicsGeometry.Count(); i < numParts; i++)
  465.                                 {
  466.                                         gp.q = m_dynamicData.physicsGeometry[i].q;
  467.                                         gp.pos = m_dynamicData.physicsGeometry[i].pos;
  468.  
  469.                                         abox.size = m_dynamicData.physicsGeometry[i].size;
  470.  
  471.                                         pPhysGeom = pGeoman->RegisterGeometry(pGeoman->CreatePrimitive(primitives::box::type, &abox), matid);
  472.                                         pPhysGeom->pGeom->Release();
  473.                                         m_pPhysEnt->AddGeometry(pPhysGeom, &gp);
  474.                                         pGeoman->UnregisterGeometry(pPhysGeom);
  475.                                 }
  476.                         }
  477.                 }
  478.         }
  479.  
  480.         // activate rendering
  481.         Get3DEngine()->RegisterEntity(this);
  482. }
  483.  
  484. void CRoadRenderNode::SetSortPriority(uint8 sortPrio)
  485. {
  486.         m_sortPrio = sortPrio;
  487. }
  488.  
  489. void CRoadRenderNode::SetIgnoreTerrainHoles(bool bVal)
  490. {
  491.         m_bIgnoreTerrainHoles = bVal;
  492. }
  493.  
  494. void CRoadRenderNode::Render(const SRendParams& RendParams, const SRenderingPassInfo& passInfo)
  495. {
  496.         FUNCTION_PROFILER_3DENGINE;
  497.  
  498.         if (!passInfo.RenderRoads())
  499.                 return; // false;
  500.  
  501.         CRenderObject* pObj = 0;
  502.  
  503.         if (GetObjManager()->AddOrCreatePersistentRenderObject(m_pTempData, pObj, NULL, passInfo))
  504.                 return;
  505.  
  506.         pObj->m_pRenderNode = this;
  507.         pObj->m_ObjFlags |= RendParams.dwFObjFlags;
  508.         pObj->m_II.m_AmbColor = RendParams.AmbientColor;
  509.         Vec3 vWSBoxCenter = m_serializedData.worldSpaceBBox.GetCenter();
  510.         pObj->m_editorSelectionID = m_nEditorSelectionID;
  511.         vWSBoxCenter.z += 0.01f;
  512.         pObj->m_II.m_Matrix.SetTranslation(vWSBoxCenter);
  513.  
  514.         //RendParams.nRenderList = EFSLIST_DECAL;
  515.  
  516.         pObj->m_nSort = m_sortPrio;
  517.  
  518.         //      if (RendParams.pShadowMapCasters)
  519.         pObj->m_ObjFlags |= (FOB_DECAL | FOB_INSHADOW | FOB_NO_FOG | FOB_TRANS_TRANSLATE);
  520.  
  521.         if (RendParams.pTerrainTexInfo && (RendParams.dwFObjFlags & (FOB_BLEND_WITH_TERRAIN_COLOR /* | FOB_AMBIENT_OCCLUSION*/)))
  522.         {
  523.                 SRenderObjData* pOD = pObj->GetObjData();
  524.                 pOD->m_pTerrainSectorTextureInfo = RendParams.pTerrainTexInfo;
  525.                 pOD->m_fMaxViewDistance = m_fWSMaxViewDist;
  526.  
  527.                 pObj->m_nTextureID = RendParams.pTerrainTexInfo->nTex0;
  528.                 //pObj->m_nTextureID1 = _RendParams.pTerrainTexInfo->nTex1;
  529.                 pOD->m_fTempVars[0] = RendParams.pTerrainTexInfo->fTexOffsetX;
  530.                 pOD->m_fTempVars[1] = RendParams.pTerrainTexInfo->fTexOffsetY;
  531.                 pOD->m_fTempVars[2] = RendParams.pTerrainTexInfo->fTexScale;
  532.                 pOD->m_fTempVars[3] = 0;
  533.                 pOD->m_fTempVars[4] = 0;
  534.         }
  535.  
  536.         if (m_pRenderMesh)
  537.         {
  538.                 pObj->m_pCurrMaterial = m_pMaterial;
  539.                 m_pRenderMesh->Render(pObj, passInfo);
  540.         }
  541. }
  542.  
  543. bool CRoadRenderNode::ClipTriangle(PodArray<Vec3>& lstVerts, PodArray<vtx_idx>& lstInds, int nStartIdxId, Plane* pPlanes)
  544. {
  545.         const PodArray<Vec3>& clipped = s_tmpClipContext.Clip(
  546.           lstVerts[lstInds[nStartIdxId + 0]],
  547.           lstVerts[lstInds[nStartIdxId + 1]],
  548.           lstVerts[lstInds[nStartIdxId + 2]],
  549.           pPlanes, 4);
  550.  
  551.         if (clipped.Count() < 3)
  552.         {
  553.                 lstInds.Delete(nStartIdxId, 3);
  554.                 return true; // entire triangle is clipped away
  555.         }
  556.  
  557.         if (clipped.Count() == 3)
  558.                 if (clipped[0].IsEquivalent(lstVerts[lstInds[nStartIdxId + 0]]))
  559.                         if (clipped[1].IsEquivalent(lstVerts[lstInds[nStartIdxId + 1]]))
  560.                                 if (clipped[2].IsEquivalent(lstVerts[lstInds[nStartIdxId + 2]]))
  561.                                         return false;
  562.         // entire triangle is in
  563.  
  564.         // replace old triangle with several new triangles
  565.         int nStartId = lstVerts.Count();
  566.         lstVerts.AddList(clipped);
  567.  
  568.         // put first new triangle into position of original one
  569.         lstInds[nStartIdxId + 0] = nStartId + 0;
  570.         lstInds[nStartIdxId + 1] = nStartId + 1;
  571.         lstInds[nStartIdxId + 2] = nStartId + 2;
  572.  
  573.         // put others in the end
  574.         for (int i = 1; i < clipped.Count() - 2; i++)
  575.         {
  576.                 lstInds.Add(nStartId + 0);
  577.                 lstInds.Add(nStartId + i + 1);
  578.                 lstInds.Add(nStartId + i + 2);
  579.         }
  580.  
  581.         return false;
  582. }
  583.  
  584. void CRoadRenderNode::SetMaterial(IMaterial* pMat)
  585. {
  586.         m_pMaterial = pMat;
  587. }
  588.  
  589. void CRoadRenderNode::Dephysicalize(bool bKeepIfReferenced)
  590. {
  591.         if (m_pPhysEnt)
  592.                 GetPhysicalWorld()->DestroyPhysicalEntity(m_pPhysEnt);
  593.         m_pPhysEnt = NULL;
  594. }
  595.  
  596. void CRoadRenderNode::GetMemoryUsage(ICrySizer* pSizer) const
  597. {
  598.         SIZER_COMPONENT_NAME(pSizer, "Road");
  599.         pSizer->AddObject(this, sizeof(*this));
  600.         pSizer->AddObject(m_arrVerts);
  601.  
  602.         pSizer->AddObject(m_dynamicData.vertices);
  603.         pSizer->AddObject(m_dynamicData.indices);
  604.         pSizer->AddObject(m_dynamicData.tangents);
  605. }
  606.  
  607. void CRoadRenderNode::ScheduleRebuild(bool bFullRebuild)
  608. {
  609.         m_bRebuildFull = bFullRebuild;
  610.  
  611.         if (Get3DEngine()->m_lstRoadRenderNodesForUpdate.Find(this) < 0)
  612.                 Get3DEngine()->m_lstRoadRenderNodesForUpdate.Add(this);
  613. }
  614.  
  615. void CRoadRenderNode::OnTerrainChanged()
  616. {
  617.         if (!m_pRenderMesh)
  618.                 return;
  619.  
  620.         int nPosStride = 0;
  621.  
  622.         IRenderMesh::ThreadAccessLock lock(m_pRenderMesh);
  623.  
  624.         byte* pPos = m_pRenderMesh->GetPosPtr(nPosStride, FSL_SYSTEM_UPDATE);
  625.  
  626.         Vec3 vWSBoxCenter = m_serializedData.worldSpaceBBox.GetCenter(); //vWSBoxCenter.z=0;
  627.  
  628.         for (int i = 0, nVertsNum = m_pRenderMesh->GetVerticesCount(); i < nVertsNum; i++)
  629.         {
  630.                 Vec3& vPos = *(Vec3*)&pPos[i * nPosStride];
  631.                 vPos.z = GetTerrain()->GetZApr(vWSBoxCenter.x + vPos.x, vWSBoxCenter.y + vPos.y, /*m_nSID*/ GetDefSID()) + 0.01f - vWSBoxCenter.z;
  632.         }
  633.         m_pRenderMesh->UnlockStream(VSF_GENERAL);
  634.  
  635.         // Terrain changed, schedule a full rebuild of the road to match
  636.         ScheduleRebuild(true);
  637. }
  638.  
  639. void CRoadRenderNode::OnRenderNodeBecomeVisible(const SRenderingPassInfo& passInfo)
  640. {
  641.         assert(m_pTempData);
  642.         m_pTempData->userData.objMat.SetIdentity();
  643. }
  644.  
  645. void CRoadRenderNode::GetTexCoordInfo(float* pTexCoordInfo)
  646. {
  647.         pTexCoordInfo[0] = m_serializedData.arrTexCoors[0];
  648.         pTexCoordInfo[1] = m_serializedData.arrTexCoors[1];
  649.         pTexCoordInfo[2] = m_serializedData.arrTexCoorsGlobal[0];
  650.         pTexCoordInfo[3] = m_serializedData.arrTexCoorsGlobal[1];
  651. }
  652.  
  653. void CRoadRenderNode::GetClipPlanes(Plane* pPlanes, int nPlanesNum, int nVertId)
  654. {
  655.         const Vec3* pVerts = &m_arrVerts[nVertId];
  656.  
  657.         if (
  658.           pVerts[0] == pVerts[1] ||
  659.           pVerts[1] == pVerts[2] ||
  660.           pVerts[2] == pVerts[3] ||
  661.           pVerts[3] == pVerts[0])
  662.                 return;
  663.  
  664.         assert(nPlanesNum == 4 || nPlanesNum == 6);
  665.  
  666.         // define 6 clip planes
  667.         pPlanes[0].SetPlane(pVerts[0], pVerts[1], pVerts[1] + Vec3(0, 0, 1));
  668.         pPlanes[1].SetPlane(pVerts[2], pVerts[3], pVerts[3] + Vec3(0, 0, -1));
  669.         pPlanes[2].SetPlane(pVerts[0], pVerts[2], pVerts[2] + Vec3(0, 0, -1));
  670.         pPlanes[3].SetPlane(pVerts[1], pVerts[3], pVerts[3] + Vec3(0, 0, 1));
  671.  
  672.         if (nPlanesNum == 6)
  673.         {
  674.                 Vec3 vHeight(0, 0, fRoadAreaZRange);
  675.                 pPlanes[4].SetPlane(pVerts[0] - vHeight, pVerts[1] - vHeight, pVerts[2] - vHeight);
  676.                 pPlanes[5].SetPlane(pVerts[1] + vHeight, pVerts[0] + vHeight, pVerts[2] + vHeight);
  677.         }
  678. }
  679.  
  680. void CRoadRenderNode::OffsetPosition(const Vec3& delta)
  681. {
  682.         if (m_pTempData) m_pTempData->OffsetPosition(delta);
  683.         m_serializedData.worldSpaceBBox.Move(delta);
  684. }
  685.  
  686. ///////////////////////////////////////////////////////////////////////////////
  687. void CRoadRenderNode::FillBBox(AABB& aabb)
  688. {
  689.         aabb = CRoadRenderNode::GetBBox();
  690. }
  691.  
  692. EERType CRoadRenderNode::GetRenderNodeType()
  693. {
  694.         return eERType_Road;
  695. }
  696.  
  697. float CRoadRenderNode::GetMaxViewDist()
  698. {
  699.         if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
  700.                 return max(GetCVars()->e_ViewDistMin, CRoadRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatioDetail * GetViewDistRatioNormilized());
  701.  
  702.         return max(GetCVars()->e_ViewDistMin, CRoadRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistRatioNormilized());
  703. }
  704.  
  705. Vec3 CRoadRenderNode::GetPos(bool) const
  706. {
  707.         return m_serializedData.worldSpaceBBox.GetCenter();
  708. }
  709.  
  710. IMaterial* CRoadRenderNode::GetMaterial(Vec3* pHitPos) const
  711. {
  712.         return m_pMaterial;
  713. }
  714.  
downloadRoadRenderNode.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top