Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // AlphaEngine API/SDK+AlphaEditor
- //
- // Programmers
- // Vivienne Anthony <[email protected]>
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- #include "AlphaEngineStd.h"
- #include <AlphaEngine/GameLogic/BaseGameLogic.h>
- #include <Urho3D/Graphics/OcclusionBuffer.h>
- #include <Urho3D/Scene/Node.h>
- #include <Urho3D/Math/Polyhedron.h>
- #include "Graphics3D/SphereTerrain/STDefines.h"
- #include <Graphics3D/SphereTerrain/SphereTerrain.h>
- #include <Graphics3D/SphereTerrain/Face/SphereTerrainFace.h>
- #include <Graphics3D/SphereTerrain/Face/Node/SphereTerrainNode.h>
- #include <Graphics3D/SphereTerrain/Face/Node/Patch/Topology/SphereTerrainTopology.h>
- #include <Graphics3D/SphereTerrain/Face/Node/Patch/SphereTerrainPatch.h>
- #include <Graphics3D/SphereTerrain/RidgedNoise/RidgedNoise.h>
- extern const char* GEOMETRY_CATEGORY;
- float SplitDistanceScale = 2.0f;
- using namespace Urho3D;
- SphereTerrainPatch::SphereTerrainPatch(Context * context,
- SphereTerrainNode * node = nullptr) :
- Drawable(context, DRAWABLE_GEOMETRY), m_pPatchParentNode(node), m_pVertexBuffer(
- new VertexBuffer(context)), m_pIndexBuffer(
- new IndexBuffer(context)), m_pGeometry(new Geometry(context)), m_pTopology(
- new SphereTerrainTopology(context, this)), m_pOcclusionBuffer(
- new OcclusionBuffer(context)), m_pModel(new Model(context)) {
- // Resize batches
- batches_.Resize(1);
- // Set geometry and non-instancing
- batches_[0].geometry_ = m_pGeometry;
- batches_[0].geometryType_ = GEOM_STATIC_NOINSTANCING;
- }
- // Register Object
- void SphereTerrainPatch::RegisterObject(Context* context) {
- context->RegisterFactory<SphereTerrainPatch>();
- }
- // Set Patch Parent Node
- void SphereTerrainPatch::SetPatchParentNode(
- SphereTerrainNode * sphereTerrainNode) {
- m_pPatchParentNode = sphereTerrainNode;
- }
- // Get Visual Radius
- double SphereTerrainPatch::GetVisualRadius() {
- return m_pPatchParentNode->GetVisualRadius();
- }
- // Build Topology and Generate Mesh
- void SphereTerrainPatch::Build() {
- // Debug
- ALPHAENGINE_LOGINFO("Generate Topology ...");
- // Cache
- Vector3 vectordata, vec;
- // Generate Topology and Describe the Type
- m_pTopology->GenerateTopology();
- // Get Topology and set Vertex Buffer
- ALPHAENGINE_LOGINFO("Create vertex data ...");
- // We could use the "legacy" element bitmask to define elements for more compact code, but let's demonstrate
- // defining the vertex elements explicitly to allow any element types and order
- PODVector<VertexElement> elements;
- elements.Push(VertexElement(TYPE_VECTOR3, SEM_POSITION));
- elements.Push(VertexElement(TYPE_VECTOR3, SEM_POSITION));
- m_pVertexBuffer->SetSize(m_pTopology->GetVertexCounts(),
- MASK_POSITION | MASK_NORMAL, false);
- ALPHAENGINE_LOGINFO("Set vertex data ...");
- m_pVertexBuffer->SetData((unsigned int *) m_pTopology->GetVertexData());
- // Set Index Buffer Shadowed
- m_pVertexBuffer->SetShadowed(true);
- ALPHAENGINE_LOGINFO("Set index data ...");
- m_pIndexBuffer->SetSize(m_pTopology->GetIndexCounts(), true, true);
- m_pIndexBuffer->SetData((unsigned int *) m_pTopology->GetIndexData());
- // Set shadow to true
- m_pIndexBuffer->SetShadowed(true);
- // Set data range
- m_pIndexBuffer->SetDataRange(m_pTopology->GetIndexData(), 0,
- m_pTopology->GetIndexCounts(), false);
- // Set Geometry to VertexBuffer
- m_pGeometry->SetNumVertexBuffers(1);
- m_pGeometry->SetVertexBuffer(0, m_pVertexBuffer);
- m_pGeometry->SetIndexBuffer(m_pIndexBuffer);
- // Set Draw Range
- m_pGeometry->SetDrawRange(TRIANGLE_LIST, 0, m_pTopology->GetIndexCounts());
- // Add to BOunding box
- ALPHAENGINE_LOGINFO("Vertex Data (Triangles<3) ...");
- const float * vectorData = m_pTopology->GetVertexData();
- const unsigned int * indexData = m_pTopology->GetIndexData();
- // Add to BOunding box
- ALPHAENGINE_LOGINFO("Generate bounding box ...");
- // Create a bounding box
- BoundingBox box;
- Polyhedron poly;
- // Clear
- box.Clear();
- // Get Vertex Data
- float * vertexs = m_pTopology->GetVertexData();
- for (unsigned int i = 0; i < m_pTopology->GetVertexCounts() * 5; i += 15) {
- Vector3 vec1(vertexs[i], vertexs[i + 1], vertexs[i + 2]);
- Vector3 vec2(vertexs[i + 5], vertexs[i + 6], vertexs[i + 7]);
- Vector3 vec3(vertexs[i + 10], vertexs[i + 11], vertexs[i + 12]);
- poly.AddFace(vec1, vec2, vec3);
- }
- // Merge Poly
- boundingBox_.Merge(poly);
- }
- SphereTerrainPatch::~SphereTerrainPatch() {
- }
- void SphereTerrainPatch::OnWorldBoundingBoxUpdate() {
- worldBoundingBox_ = boundingBox_.Transformed(node_->GetWorldTransform());
- }
- STFaceDirection SphereTerrainPatch::GetFaceDirection() {
- m_pPatchParentNode->GetFaceDirection();
- }
- void SphereTerrainPatch::SetMaterial(Material * material) {
- // Set material
- m_pMaterial = material;
- // set material
- for (unsigned i = 0; i < batches_.Size(); ++i)
- batches_[i].material_ = material;
- }
- bool SphereTerrainPatch::DrawOcclusion(OcclusionBuffer* buffer) {
- bool success = true;
- if (!m_pGeometry) {
- return false;
- }
- // Check that the material is suitable for occlusion (default material always is) and set culling mode
- buffer->SetCullMode(CULL_CCW);
- const unsigned char* vertexData;
- unsigned vertexSize;
- const unsigned char* indexData;
- unsigned indexSize;
- const PODVector<VertexElement>* elements;
- m_pGeometry->GetRawData(vertexData, vertexSize, indexData, indexSize,
- elements);
- // Check for valid geometry data
- if (!vertexData || !elements
- || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3,
- SEM_POSITION) != 0) {
- return false;
- }
- // Draw and check for running out of triangles
- success = buffer->AddTriangles(this->GetNode()->GetWorldTransform(),
- vertexData, vertexSize, m_pGeometry->GetVertexStart(),
- m_pGeometry->GetVertexCount());
- return success;
- }
- // Update Terrain Patch Per Frame
- void SphereTerrainPatch::UpdateBatches(const FrameInfo& frame) {
- const Matrix3x4& worldTransform = node_->GetWorldTransform();
- distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
- cache_scale = worldTransform.Scale().DotProduct(DOT_SCALE);
- lodDistance_ = frame.camera_->GetLodDistance(distance_, cache_scale,
- lodBias_);
- // Prevent setting distance and transfomr if no batch
- if (!batches_.Size()) {
- return;
- }
- // Update Distance and World Transform
- batches_[0].distance_ = distance_;
- batches_[0].worldTransform_ = &worldTransform;
- }
- // Process Ray Query
- void SphereTerrainPatch::ProcessRayQuery(const RayOctreeQuery& query,
- PODVector<RayQueryResult>& results) {
- RayQueryLevel level = query.level_;
- switch (level) {
- case RAY_AABB:
- Drawable::ProcessRayQuery(query, results);
- break;
- case RAY_OBB:
- case RAY_TRIANGLE: {
- Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
- Ray localRay = query.ray_.Transformed(inverse);
- float distance = localRay.HitDistance(boundingBox_);
- Vector3 normal = -query.ray_.direction_;
- if (level == RAY_TRIANGLE && distance < query.maxDistance_) {
- Vector3 geometryNormal;
- distance = m_pGeometry->GetHitDistance(localRay, &geometryNormal);
- normal =
- (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized();
- }
- if (distance < query.maxDistance_) {
- RayQueryResult result;
- result.position_ = query.ray_.origin_
- + distance * query.ray_.direction_;
- result.normal_ = normal;
- result.distance_ = distance;
- result.drawable_ = this;
- result.node_ = node_;
- result.subObject_ = M_MAX_UNSIGNED;
- results.Push(result);
- }
- }
- break;
- case RAY_TRIANGLE_UV:
- URHO3D_LOGWARNING(
- "RAY_TRIANGLE_UV query level is not supported for TerrainPatch component");
- break;
- }
- }
- void SphereTerrainPatch::DrawDebugGeometry(DebugRenderer* debug,
- bool depthTest) {
- }
- void SphereTerrainPatch::SetSphereTerrain(SphereTerrain * sphereTerrain) {
- // Set Sphere Terrain Owner
- m_pSphereTerrain = sphereTerrain;
- }
- Vector2 SphereTerrainPatch::GetCoordinates() const {
- return m_pPatchParentNode->GetCoordinates();
- }
- unsigned int SphereTerrainPatch::GetDepth() const {
- return m_pPatchParentNode->GetDepth();
- }
- // Get Height Scale
- double SphereTerrainPatch::GetHeightScale() {
- return m_pSphereTerrain->GetHeightScale();
- }
- // Get Gain
- double SphereTerrainPatch::GetGain() {
- return m_pSphereTerrain->GetGain();
- }
- // GetOctaves
- unsigned int SphereTerrainPatch::GetOctaves() {
- return m_pSphereTerrain->GetOctaves();
- }
- // Get Lacunarity
- double SphereTerrainPatch::GetLacunarity() {
- return m_pSphereTerrain->GetLacunarity();
- }
- // Get Offset
- double SphereTerrainPatch::GetOffset() {
- return m_pSphereTerrain->GetOffset();
- }
- // Get H
- double SphereTerrainPatch::GetH() {
- return m_pSphereTerrain->GetH();
- }
- // Update Geometry if Data Lost
- void SphereTerrainPatch::UpdateGeometry(const FrameInfo& frame) {
- if (m_pVertexBuffer->IsDataLost() && m_pIndexBuffer->IsDataLost()) {
- Build();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment