Geometry BubbleEmitter::CreateGeometry( unsigned int numOfPatch ) { unsigned int numVertex = numOfPatch*4u; std::vector<Vertex> vertexData; vertexData.reserve( numVertex ); unsigned int numIndex = numOfPatch*6u; Vector<unsigned int> indexData; indexData.Reserve( numIndex ); for(unsigned int i = 0; i < numOfPatch; i++) { float curSize = RandomRange(mBubbleSizeRange.x, mBubbleSizeRange.y, mRandomSeed); float index = static_cast<float>( i ); vertexData.push_back( Vertex( index, Vector2(0.f,0.f), Vector2(0.f,0.f) ) ); vertexData.push_back( Vertex( index, Vector2(0.f,curSize), Vector2(0.f,1.f) ) ); vertexData.push_back( Vertex( index, Vector2(curSize,curSize), Vector2(1.f,1.f) ) ); vertexData.push_back( Vertex( index, Vector2(curSize,0.f), Vector2(1.f,0.f) ) ); unsigned int idx = index * 4; indexData.PushBack( idx ); indexData.PushBack( idx+1 ); indexData.PushBack( idx+2 ); indexData.PushBack( idx ); indexData.PushBack( idx+2 ); indexData.PushBack( idx+3 ); } Property::Map vertexFormat; vertexFormat["aIndex"] = Property::FLOAT; vertexFormat["aPosition"] = Property::VECTOR2; vertexFormat["aTexCoord"] = Property::VECTOR2; PropertyBuffer vertices = PropertyBuffer::New( vertexFormat, numVertex ); vertices.SetData( &vertexData[0] ); Property::Map indexFormat; indexFormat["indices"] = Property::INTEGER; PropertyBuffer indices = PropertyBuffer::New( indexFormat, numIndex ); indices.SetData( &indexData[0] ); Geometry geometry = Geometry::New(); geometry.AddVertexBuffer( vertices ); geometry.SetIndexBuffer( indices ); return geometry; }
bool Model::EndLoad() { // Upload vertex buffer data for (unsigned i = 0; i < vertexBuffers_.Size(); ++i) { VertexBuffer* buffer = vertexBuffers_[i]; VertexBufferDesc& desc = loadVBData_[i]; if (desc.data_) { buffer->SetShadowed(true); buffer->SetSize(desc.vertexCount_, desc.vertexElements_); buffer->SetData(desc.data_.Get()); } } // Upload index buffer data for (unsigned i = 0; i < indexBuffers_.Size(); ++i) { IndexBuffer* buffer = indexBuffers_[i]; IndexBufferDesc& desc = loadIBData_[i]; if (desc.data_) { buffer->SetShadowed(true); buffer->SetSize(desc.indexCount_, desc.indexSize_ > sizeof(unsigned short)); buffer->SetData(desc.data_.Get()); } } // Set up geometries for (unsigned i = 0; i < geometries_.Size(); ++i) { for (unsigned j = 0; j < geometries_[i].Size(); ++j) { Geometry* geometry = geometries_[i][j]; GeometryDesc& desc = loadGeometries_[i][j]; geometry->SetVertexBuffer(0, vertexBuffers_[desc.vbRef_]); geometry->SetIndexBuffer(indexBuffers_[desc.ibRef_]); geometry->SetDrawRange(desc.type_, desc.indexStart_, desc.indexCount_); } } loadVBData_.Clear(); loadIBData_.Clear(); loadGeometries_.Clear(); return true; }
/** * @brief Creates a geometry object from vertices and indices. * @param[in] vertices The object vertices * @param[in] indices The object indices * @return A geometry object */ Geometry CreateTexturedGeometry( Vector<TexturedVertex>& vertices, Vector<unsigned short>& indices ) { // Vertices Property::Map vertexFormat; vertexFormat[POSITION] = Property::VECTOR3; vertexFormat[NORMAL] = Property::VECTOR3; vertexFormat[TEXTURE] = Property::VECTOR2; PropertyBuffer surfaceVertices = PropertyBuffer::New( vertexFormat ); surfaceVertices.SetData( &vertices[0u], vertices.Size() ); Geometry geometry = Geometry::New(); geometry.AddVertexBuffer( surfaceVertices ); // Indices for triangle formulation geometry.SetIndexBuffer( &indices[0u], indices.Size() ); return geometry; }
/** * Set a PropertyBuffer to be used as a source of indices for the geometry * * This buffer is required to have exactly one component and it must be of the * type dali.PROPERTY_INTEGER * * By setting this buffer it will cause the geometry to be rendered using indices. * To unset call SetIndexBuffer with an empty handle. * * @method setIndexBuffer * @for Geometry * @param {Object} indexBuffer PropertyBuffer to be used as a source of indices * for the geometry */ void GeometryApi::SetIndexBuffer( const v8::FunctionCallbackInfo<v8::Value>& args ) { v8::Isolate* isolate = args.GetIsolate(); v8::HandleScope handleScope( isolate ); Geometry geometry = GetGeometry( isolate, args ); bool found( false ); PropertyBuffer indexBuffer = PropertyBufferApi::GetPropertyBufferFromParams( 0, found, isolate, args ); if( !found ) { DALI_SCRIPT_EXCEPTION( isolate, "invalid property buffer parameter" ); } else { geometry.SetIndexBuffer(indexBuffer); } }
Geometry CreateQuadGeometry(void) { PropertyBuffer vertexData = CreatePropertyBuffer(); const float halfQuadSize = .5f; struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; }; TexturedQuadVertex texturedQuadVertexData[4] = { { Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f) }, { Vector2( halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f) }, { Vector2(-halfQuadSize, halfQuadSize), Vector2(0.f, 1.f) }, { Vector2( halfQuadSize, halfQuadSize), Vector2(1.f, 1.f) } }; vertexData.SetData(texturedQuadVertexData, 4); unsigned short indexData[6] = { 0, 3, 1, 0, 2, 3 }; Geometry geometry = Geometry::New(); geometry.AddVertexBuffer( vertexData ); geometry.SetIndexBuffer( indexData, sizeof(indexData)/sizeof(indexData[0]) ); return geometry; }
void Terrain::CreatePatchGeometry(TerrainPatch* patch) { URHO3D_PROFILE(CreatePatchGeometry); unsigned row = (unsigned)(patchSize_ + 1); VertexBuffer* vertexBuffer = patch->GetVertexBuffer(); Geometry* geometry = patch->GetGeometry(); Geometry* maxLodGeometry = patch->GetMaxLodGeometry(); Geometry* occlusionGeometry = patch->GetOcclusionGeometry(); if (vertexBuffer->GetVertexCount() != row * row) vertexBuffer->SetSize(row * row, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT); SharedArrayPtr<unsigned char> cpuVertexData(new unsigned char[row * row * sizeof(Vector3)]); SharedArrayPtr<unsigned char> occlusionCpuVertexData(new unsigned char[row * row * sizeof(Vector3)]); float* vertexData = (float*)vertexBuffer->Lock(0, vertexBuffer->GetVertexCount()); float* positionData = (float*)cpuVertexData.Get(); float* occlusionData = (float*)occlusionCpuVertexData.Get(); BoundingBox box; unsigned occlusionLevel = occlusionLodLevel_; if (occlusionLevel > numLodLevels_ - 1) occlusionLevel = numLodLevels_ - 1; if (vertexData) { const IntVector2& coords = patch->GetCoordinates(); int lodExpand = (1 << (occlusionLevel)) - 1; int halfLodExpand = (1 << (occlusionLevel)) / 2; for (int z = 0; z <= patchSize_; ++z) { for (int x = 0; x <= patchSize_; ++x) { int xPos = coords.x_ * patchSize_ + x; int zPos = coords.y_ * patchSize_ + z; // Position Vector3 position((float)x * spacing_.x_, GetRawHeight(xPos, zPos), (float)z * spacing_.z_); *vertexData++ = position.x_; *vertexData++ = position.y_; *vertexData++ = position.z_; *positionData++ = position.x_; *positionData++ = position.y_; *positionData++ = position.z_; box.Merge(position); // For vertices that are part of the occlusion LOD, calculate the minimum height in the neighborhood // to prevent false positive occlusion due to inaccuracy between occlusion LOD & visible LOD float minHeight = position.y_; if (halfLodExpand > 0 && (x & lodExpand) == 0 && (z & lodExpand) == 0) { int minX = Max(xPos - halfLodExpand, 0); int maxX = Min(xPos + halfLodExpand, numVertices_.x_ - 1); int minZ = Max(zPos - halfLodExpand, 0); int maxZ = Min(zPos + halfLodExpand, numVertices_.y_ - 1); for (int nZ = minZ; nZ <= maxZ; ++nZ) { for (int nX = minX; nX <= maxX; ++nX) minHeight = Min(minHeight, GetRawHeight(nX, nZ)); } } *occlusionData++ = position.x_; *occlusionData++ = minHeight; *occlusionData++ = position.z_; // Normal Vector3 normal = GetRawNormal(xPos, zPos); *vertexData++ = normal.x_; *vertexData++ = normal.y_; *vertexData++ = normal.z_; // Texture coordinate Vector2 texCoord((float)xPos / (float)numVertices_.x_, 1.0f - (float)zPos / (float)numVertices_.y_); *vertexData++ = texCoord.x_; *vertexData++ = texCoord.y_; // Tangent Vector3 xyz = (Vector3::RIGHT - normal * normal.DotProduct(Vector3::RIGHT)).Normalized(); *vertexData++ = xyz.x_; *vertexData++ = xyz.y_; *vertexData++ = xyz.z_; *vertexData++ = 1.0f; } } vertexBuffer->Unlock(); vertexBuffer->ClearDataLost(); } patch->SetBoundingBox(box); if (drawRanges_.Size()) { unsigned occlusionDrawRange = occlusionLevel << 4; geometry->SetIndexBuffer(indexBuffer_); geometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false); geometry->SetRawVertexData(cpuVertexData, MASK_POSITION); maxLodGeometry->SetIndexBuffer(indexBuffer_); maxLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false); maxLodGeometry->SetRawVertexData(cpuVertexData, MASK_POSITION); occlusionGeometry->SetIndexBuffer(indexBuffer_); occlusionGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[occlusionDrawRange].first_, drawRanges_[occlusionDrawRange].second_, false); occlusionGeometry->SetRawVertexData(occlusionCpuVertexData, MASK_POSITION); } patch->ResetLod(); }
void Terrain::CreatePatchGeometry(TerrainPatch* patch) { PROFILE(CreatePatchGeometry); unsigned row = patchSize_ + 1; VertexBuffer* vertexBuffer = patch->GetVertexBuffer(); Geometry* geometry = patch->GetGeometry(); Geometry* maxLodGeometry = patch->GetMaxLodGeometry(); Geometry* minLodGeometry = patch->GetMinLodGeometry(); if (vertexBuffer->GetVertexCount() != row * row) vertexBuffer->SetSize(row * row, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT); SharedArrayPtr<unsigned char> cpuVertexData(new unsigned char[row * row * sizeof(Vector3)]); float* vertexData = (float*)vertexBuffer->Lock(0, vertexBuffer->GetVertexCount()); float* positionData = (float*)cpuVertexData.Get(); BoundingBox box; if (vertexData) { const IntVector2& coords = patch->GetCoordinates(); for (int z1 = 0; z1 <= patchSize_; ++z1) { for (int x1 = 0; x1 <= patchSize_; ++x1) { int xPos = coords.x_ * patchSize_ + x1; int zPos = coords.y_ * patchSize_ + z1; // Position Vector3 position((float)x1 * spacing_.x_, GetRawHeight(xPos, zPos), (float)z1 * spacing_.z_); *vertexData++ = position.x_; *vertexData++ = position.y_; *vertexData++ = position.z_; *positionData++ = position.x_; *positionData++ = position.y_; *positionData++ = position.z_; box.Merge(position); // Normal Vector3 normal = GetRawNormal(xPos, zPos); *vertexData++ = normal.x_; *vertexData++ = normal.y_; *vertexData++ = normal.z_; // Texture coordinate Vector2 texCoord((float)xPos / (float)numVertices_.x_, 1.0f - (float)zPos / (float)numVertices_.y_); *vertexData++ = texCoord.x_; *vertexData++ = texCoord.y_; // Tangent Vector3 xyz = (Vector3::RIGHT - normal * normal.DotProduct(Vector3::RIGHT)).Normalized(); *vertexData++ = xyz.x_; *vertexData++ = xyz.y_; *vertexData++ = xyz.z_; *vertexData++ = 1.0f; } } vertexBuffer->Unlock(); vertexBuffer->ClearDataLost(); } patch->SetBoundingBox(box); if (drawRanges_.Size()) { unsigned lastDrawRange = drawRanges_.Size() - 1; geometry->SetIndexBuffer(indexBuffer_); geometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false); geometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION); maxLodGeometry->SetIndexBuffer(indexBuffer_); maxLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false); maxLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION); minLodGeometry->SetIndexBuffer(indexBuffer_); minLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[lastDrawRange].first_, drawRanges_[lastDrawRange].second_, false); minLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION); } // Offset the occlusion geometry by vertex spacing to reduce possibility of over-aggressive occlusion patch->SetOcclusionOffset(-0.5f * (spacing_.x_ + spacing_.z_)); patch->ResetLod(); }