cgprojectsfx

SphereTerrainPatch.cpp

Feb 10th, 2018
430
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.90 KB | None | 0 0
  1. //
  2. // AlphaEngine API/SDK+AlphaEditor
  3. //
  4. // Programmers
  5. // Vivienne Anthony <[email protected]>
  6. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  7. #include "AlphaEngineStd.h"
  8.  
  9. #include <AlphaEngine/GameLogic/BaseGameLogic.h>
  10.  
  11. #include <Urho3D/Graphics/OcclusionBuffer.h>
  12.  
  13. #include <Urho3D/Scene/Node.h>
  14. #include <Urho3D/Math/Polyhedron.h>
  15.  
  16. #include "Graphics3D/SphereTerrain/STDefines.h"
  17.  
  18. #include <Graphics3D/SphereTerrain/SphereTerrain.h>
  19. #include <Graphics3D/SphereTerrain/Face/SphereTerrainFace.h>
  20. #include <Graphics3D/SphereTerrain/Face/Node/SphereTerrainNode.h>
  21. #include <Graphics3D/SphereTerrain/Face/Node/Patch/Topology/SphereTerrainTopology.h>
  22.  
  23. #include <Graphics3D/SphereTerrain/Face/Node/Patch/SphereTerrainPatch.h>
  24. #include <Graphics3D/SphereTerrain/RidgedNoise/RidgedNoise.h>
  25.  
  26. extern const char* GEOMETRY_CATEGORY;
  27.  
  28. float SplitDistanceScale = 2.0f;
  29.  
  30. using namespace Urho3D;
  31.  
  32. SphereTerrainPatch::SphereTerrainPatch(Context * context,
  33.         SphereTerrainNode * node = nullptr) :
  34.         Drawable(context, DRAWABLE_GEOMETRY), m_pPatchParentNode(node), m_pVertexBuffer(
  35.                 new VertexBuffer(context)), m_pIndexBuffer(
  36.                 new IndexBuffer(context)), m_pGeometry(new Geometry(context)), m_pTopology(
  37.                 new SphereTerrainTopology(context, this)), m_pOcclusionBuffer(
  38.                 new OcclusionBuffer(context)), m_pModel(new Model(context)) {
  39.  
  40.     // Resize batches
  41.     batches_.Resize(1);
  42.  
  43.     // Set geometry and non-instancing
  44.     batches_[0].geometry_ = m_pGeometry;
  45.     batches_[0].geometryType_ = GEOM_STATIC_NOINSTANCING;
  46.  
  47. }
  48.  
  49. // Register Object
  50. void SphereTerrainPatch::RegisterObject(Context* context) {
  51.     context->RegisterFactory<SphereTerrainPatch>();
  52. }
  53.  
  54. // Set Patch Parent Node
  55. void SphereTerrainPatch::SetPatchParentNode(
  56.         SphereTerrainNode * sphereTerrainNode) {
  57.     m_pPatchParentNode = sphereTerrainNode;
  58. }
  59.  
  60. // Get Visual Radius
  61. double SphereTerrainPatch::GetVisualRadius() {
  62.     return m_pPatchParentNode->GetVisualRadius();
  63. }
  64.  
  65. // Build Topology and Generate Mesh
  66. void SphereTerrainPatch::Build() {
  67.     // Debug
  68.     ALPHAENGINE_LOGINFO("Generate Topology ...");
  69.  
  70.     // Cache
  71.     Vector3 vectordata, vec;
  72.  
  73.     // Generate Topology and Describe the Type
  74.     m_pTopology->GenerateTopology();
  75.  
  76.     // Get Topology and set Vertex Buffer
  77.     ALPHAENGINE_LOGINFO("Create vertex data ...");
  78.  
  79.     // We could use the "legacy" element bitmask to define elements for more compact code, but let's demonstrate
  80.     // defining the vertex elements explicitly to allow any element types and order
  81.     PODVector<VertexElement> elements;
  82.     elements.Push(VertexElement(TYPE_VECTOR3, SEM_POSITION));
  83.     elements.Push(VertexElement(TYPE_VECTOR3, SEM_POSITION));
  84.  
  85.     m_pVertexBuffer->SetSize(m_pTopology->GetVertexCounts(),
  86.             MASK_POSITION | MASK_NORMAL, false);
  87.  
  88.     ALPHAENGINE_LOGINFO("Set vertex data ...");
  89.     m_pVertexBuffer->SetData((unsigned int *) m_pTopology->GetVertexData());
  90.  
  91.     // Set Index Buffer Shadowed
  92.     m_pVertexBuffer->SetShadowed(true);
  93.  
  94.     ALPHAENGINE_LOGINFO("Set index data ...");
  95.     m_pIndexBuffer->SetSize(m_pTopology->GetIndexCounts(), true, true);
  96.     m_pIndexBuffer->SetData((unsigned int *) m_pTopology->GetIndexData());
  97.  
  98.     // Set shadow to true
  99.     m_pIndexBuffer->SetShadowed(true);
  100.  
  101.     // Set data range
  102.     m_pIndexBuffer->SetDataRange(m_pTopology->GetIndexData(), 0,
  103.             m_pTopology->GetIndexCounts(), false);
  104.  
  105.     // Set Geometry to VertexBuffer
  106.     m_pGeometry->SetNumVertexBuffers(1);
  107.     m_pGeometry->SetVertexBuffer(0, m_pVertexBuffer);
  108.     m_pGeometry->SetIndexBuffer(m_pIndexBuffer);
  109.  
  110.     // Set Draw Range
  111.     m_pGeometry->SetDrawRange(TRIANGLE_LIST, 0, m_pTopology->GetIndexCounts());
  112.  
  113.     // Add to BOunding box
  114.     ALPHAENGINE_LOGINFO("Vertex Data (Triangles<3) ...");
  115.  
  116.     const float * vectorData = m_pTopology->GetVertexData();
  117.     const unsigned int * indexData = m_pTopology->GetIndexData();
  118.  
  119.     // Add to BOunding box
  120.     ALPHAENGINE_LOGINFO("Generate bounding box ...");
  121.  
  122.     // Create a bounding box
  123.     BoundingBox box;
  124.     Polyhedron poly;
  125.  
  126.     // Clear
  127.     box.Clear();
  128.  
  129.     // Get Vertex Data
  130.     float * vertexs = m_pTopology->GetVertexData();
  131.  
  132.     for (unsigned int i = 0; i < m_pTopology->GetVertexCounts() * 5; i += 15) {
  133.         Vector3 vec1(vertexs[i], vertexs[i + 1], vertexs[i + 2]);
  134.         Vector3 vec2(vertexs[i + 5], vertexs[i + 6], vertexs[i + 7]);
  135.         Vector3 vec3(vertexs[i + 10], vertexs[i + 11], vertexs[i + 12]);
  136.  
  137.         poly.AddFace(vec1, vec2, vec3);
  138.     }
  139.  
  140.     // Merge Poly
  141.     boundingBox_.Merge(poly);
  142.  
  143. }
  144.  
  145. SphereTerrainPatch::~SphereTerrainPatch() {
  146.  
  147. }
  148.  
  149. void SphereTerrainPatch::OnWorldBoundingBoxUpdate() {
  150.  
  151.     worldBoundingBox_ = boundingBox_.Transformed(node_->GetWorldTransform());
  152. }
  153.  
  154. STFaceDirection SphereTerrainPatch::GetFaceDirection() {
  155.     m_pPatchParentNode->GetFaceDirection();
  156. }
  157.  
  158. void SphereTerrainPatch::SetMaterial(Material * material) {
  159.     // Set material
  160.     m_pMaterial = material;
  161.  
  162.     // set material
  163.     for (unsigned i = 0; i < batches_.Size(); ++i)
  164.         batches_[i].material_ = material;
  165. }
  166.  
  167. bool SphereTerrainPatch::DrawOcclusion(OcclusionBuffer* buffer) {
  168.     bool success = true;
  169.  
  170.     if (!m_pGeometry) {
  171.         return false;
  172.     }
  173.  
  174.     // Check that the material is suitable for occlusion (default material always is) and set culling mode
  175.     buffer->SetCullMode(CULL_CCW);
  176.  
  177.     const unsigned char* vertexData;
  178.     unsigned vertexSize;
  179.     const unsigned char* indexData;
  180.     unsigned indexSize;
  181.     const PODVector<VertexElement>* elements;
  182.  
  183.     m_pGeometry->GetRawData(vertexData, vertexSize, indexData, indexSize,
  184.             elements);
  185.  
  186.     // Check for valid geometry data
  187.     if (!vertexData || !elements
  188.             || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3,
  189.                     SEM_POSITION) != 0) {
  190.         return false;
  191.     }
  192.  
  193.     // Draw and check for running out of triangles
  194.     success = buffer->AddTriangles(this->GetNode()->GetWorldTransform(),
  195.             vertexData, vertexSize, m_pGeometry->GetVertexStart(),
  196.             m_pGeometry->GetVertexCount());
  197.  
  198.     return success;
  199. }
  200.  
  201. // Update Terrain Patch Per Frame
  202. void SphereTerrainPatch::UpdateBatches(const FrameInfo& frame) {
  203.     const Matrix3x4& worldTransform = node_->GetWorldTransform();
  204.     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
  205.  
  206.     cache_scale = worldTransform.Scale().DotProduct(DOT_SCALE);
  207.     lodDistance_ = frame.camera_->GetLodDistance(distance_, cache_scale,
  208.             lodBias_);
  209.  
  210.     // Prevent setting distance and transfomr if no batch
  211.     if (!batches_.Size()) {
  212.         return;
  213.     }
  214.  
  215.     // Update Distance and World Transform
  216.     batches_[0].distance_ = distance_;
  217.     batches_[0].worldTransform_ = &worldTransform;
  218.  
  219. }
  220.  
  221. // Process Ray Query
  222. void SphereTerrainPatch::ProcessRayQuery(const RayOctreeQuery& query,
  223.         PODVector<RayQueryResult>& results) {
  224.     RayQueryLevel level = query.level_;
  225.  
  226.     switch (level) {
  227.     case RAY_AABB:
  228.         Drawable::ProcessRayQuery(query, results);
  229.         break;
  230.  
  231.     case RAY_OBB:
  232.     case RAY_TRIANGLE: {
  233.         Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
  234.         Ray localRay = query.ray_.Transformed(inverse);
  235.         float distance = localRay.HitDistance(boundingBox_);
  236.         Vector3 normal = -query.ray_.direction_;
  237.  
  238.         if (level == RAY_TRIANGLE && distance < query.maxDistance_) {
  239.             Vector3 geometryNormal;
  240.             distance = m_pGeometry->GetHitDistance(localRay, &geometryNormal);
  241.             normal =
  242.                     (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized();
  243.         }
  244.  
  245.         if (distance < query.maxDistance_) {
  246.             RayQueryResult result;
  247.             result.position_ = query.ray_.origin_
  248.                     + distance * query.ray_.direction_;
  249.             result.normal_ = normal;
  250.             result.distance_ = distance;
  251.             result.drawable_ = this;
  252.             result.node_ = node_;
  253.             result.subObject_ = M_MAX_UNSIGNED;
  254.             results.Push(result);
  255.         }
  256.     }
  257.         break;
  258.  
  259.     case RAY_TRIANGLE_UV:
  260.         URHO3D_LOGWARNING(
  261.                 "RAY_TRIANGLE_UV query level is not supported for TerrainPatch component");
  262.         break;
  263.     }
  264. }
  265.  
  266. void SphereTerrainPatch::DrawDebugGeometry(DebugRenderer* debug,
  267.         bool depthTest) {
  268.  
  269. }
  270.  
  271. void SphereTerrainPatch::SetSphereTerrain(SphereTerrain * sphereTerrain) {
  272.  
  273.     // Set Sphere Terrain Owner
  274.     m_pSphereTerrain = sphereTerrain;
  275. }
  276.  
  277. Vector2 SphereTerrainPatch::GetCoordinates() const {
  278.     return m_pPatchParentNode->GetCoordinates();
  279. }
  280.  
  281. unsigned int SphereTerrainPatch::GetDepth() const {
  282.     return m_pPatchParentNode->GetDepth();
  283. }
  284.  
  285. // Get Height Scale
  286. double SphereTerrainPatch::GetHeightScale() {
  287.     return m_pSphereTerrain->GetHeightScale();
  288. }
  289.  
  290. // Get Gain
  291. double SphereTerrainPatch::GetGain() {
  292.     return m_pSphereTerrain->GetGain();
  293. }
  294.  
  295. // GetOctaves
  296. unsigned int SphereTerrainPatch::GetOctaves() {
  297.  
  298.     return m_pSphereTerrain->GetOctaves();
  299. }
  300.  
  301. // Get Lacunarity
  302. double SphereTerrainPatch::GetLacunarity() {
  303.     return m_pSphereTerrain->GetLacunarity();
  304. }
  305.  
  306. // Get Offset
  307. double SphereTerrainPatch::GetOffset() {
  308.     return m_pSphereTerrain->GetOffset();
  309. }
  310.  
  311. // Get H
  312. double SphereTerrainPatch::GetH() {
  313.     return m_pSphereTerrain->GetH();
  314. }
  315.  
  316. // Update Geometry if Data Lost
  317. void SphereTerrainPatch::UpdateGeometry(const FrameInfo& frame) {
  318.     if (m_pVertexBuffer->IsDataLost() && m_pIndexBuffer->IsDataLost()) {
  319.         Build();
  320.     }
  321. }
Advertisement
Add Comment
Please, Sign In to add comment