void CC3DataReader::initOnData( CCData* data ) { _data = data; _data->retain(); _readRange = CCRangeMake(0, 0); _isBigEndian = false; _wasReadBeyondEOF = false; }
void CC3MeshParticleEmitter::copyTemplateContentToParticle( CC3MeshParticle* aParticle ) { // Get the particle template mesh CC3Mesh* templateMesh = aParticle->getTemplateMesh(); // Copy vertex content GLuint vtxCount = aParticle->getVertexCount(); GLuint firstVtx = aParticle->getFirstVertexOffset(); getMesh()->copyVertices( vtxCount, 0, templateMesh, firstVtx ); // If this mesh does not have vertex indices, we're done if ( !getMesh()->hasVertexIndices() ) return; // Copy vertex indices, taking into consideration the staring index of the vertex content in this mesh. GLuint vtxIdxCount = aParticle->getVertexIndexCount(); GLuint firstVtxIdx = aParticle->getFirstVertexIndexOffset(); getMesh()->copyVertexIndices( vtxIdxCount, 0, templateMesh, firstVtxIdx, firstVtx ); addDirtyVertexIndexRange( CCRangeMake(firstVtxIdx, vtxIdxCount) ); }
void CC3MeshParticleEmitter::removeParticle( CC3Particle* aParticle, GLuint anIndex ) { super::removeParticle( aParticle, anIndex ); // Decrements particleCount and vertexCount GLuint partCount = getParticleCount(); // Get the decremented particleCount // Particle being removed CC3MeshParticle* deadParticle = (CC3MeshParticle*)aParticle; GLuint deadFirstVtx = deadParticle->getFirstVertexOffset(); GLuint deadVtxCount = deadParticle->getVertexCount(); GLuint deadFirstVtxIdx = deadParticle->getFirstVertexIndexOffset(); GLuint deadVtxIdxCount = deadParticle->getVertexIndexCount(); // Last living particle CC3MeshParticle* lastParticle = getMeshParticleAt( partCount ); GLuint lastFirstVtx = lastParticle->getFirstVertexOffset(); GLuint lastVtxCount = lastParticle->getVertexCount(); GLuint lastFirstVtxIdx = lastParticle->getFirstVertexIndexOffset(); GLuint lastVtxIdxCount = lastParticle->getVertexIndexCount(); // Remove the template mesh from the particle, even if the particle will be reused. // This gives the emitter a chance to use a different template mesh when it reuses the particle. // Clear it before removing the particle, because the particle may disappear when removed from // this emitter. First, take note of whether the last particle has the same template mesh as the // last particle. This knowledge is used below when copying vertex indices. bool isSameTemplateMesh = (deadParticle->getTemplateMesh() == lastParticle->getTemplateMesh()); deadParticle->setTemplateMesh( NULL ); if (anIndex >= partCount) { CC3_TRACE("[ptc]Removing particle at %d by doing nothing, since particle count is now %d.", anIndex, partCount); } else if (deadVtxCount == lastVtxCount && deadVtxIdxCount == lastVtxIdxCount) { // If the two particles have the same number of vertices and vertex indices, we can swap them. CC3_TRACE("[ptc]Removing particle at %d by swapping particles of identical size.", anIndex); // Move the last living particle into the slot that is being vacated m_particles->exchangeObjectAtIndex( anIndex, partCount ); // Swap the vertex offsets of the two particles deadParticle->setFirstVertexOffset( lastFirstVtx ); deadParticle->setFirstVertexIndexOffset( lastFirstVtxIdx ); lastParticle->setFirstVertexOffset( deadFirstVtx ); lastParticle->setFirstVertexIndexOffset( deadFirstVtxIdx ); // Update the underlying mesh vertex content and mark the updated vertex dirty getMesh()->copyVertices( deadVtxCount, lastFirstVtx, deadFirstVtx ); addDirtyVertexRange( deadParticle->getVertexRange() ); // If the template meshes are the same, we don't need to update the vertex indices. if ( !isSameTemplateMesh ) { getMesh()->getVertexIndices()->copyVertices( lastVtxIdxCount, lastFirstVtxIdx, deadFirstVtxIdx, (deadFirstVtx - lastFirstVtx) ); addDirtyVertexIndexRange( deadParticle->getVertexIndexRange() ); } } else { CC3_TRACE("[ptc]Removing particle at %d by removing particle with %d vertices from collection.", anIndex, deadVtxCount); // Move the vertices in the mesh to fill the gap created by the removed particle GLuint srcVtxStart = (deadFirstVtx + deadVtxCount); // Start after removed particle GLuint srcVtxEnd = (lastFirstVtx + lastVtxCount); // End after last living particle GLuint vtxCount = srcVtxEnd - srcVtxStart; GLuint dstVtxStart = deadFirstVtx; getMesh()->copyVertices( vtxCount, srcVtxStart, dstVtxStart ); addDirtyVertexRange( CCRangeMake(dstVtxStart, vtxCount) ); // If the mesh has vertex indices, move them to fill the gap created by the removed particle // and adjust their values to fill the gap created in the vertex content. GLuint srcVtxIdxStart = (deadFirstVtxIdx + deadVtxIdxCount); // Start after removed particle GLuint srcVtxIdxEnd = (lastFirstVtxIdx + lastVtxIdxCount); // End after last living particle GLuint vtxIdxCount = srcVtxIdxEnd - srcVtxIdxStart; GLuint dstVtxIdxStart = deadFirstVtxIdx; getMesh()->copyVertexIndices( vtxIdxCount, srcVtxIdxStart, dstVtxIdxStart, -(GLint)deadVtxCount ); addDirtyVertexIndexRange( CCRangeMake(dstVtxIdxStart, vtxIdxCount) ); // Remove the particle from particles collection, // Do this last in case the particle is only being held by this collection. m_particles->removeObjectAtIndex( anIndex ); // Adjust the firstVertexOffset and firstVertexIndexOffset properties of each remaining // particle to fill in the gap created by removing the particle from the mesh arrays. // Do this after the dead particle has been removed from the collection. for (GLuint partIdx = anIndex; partIdx < partCount; partIdx++) { CC3MeshParticle* mp = getMeshParticleAt( partIdx ); GLuint firstVertexOffset = mp->getFirstVertexOffset(); GLuint firstVertexIndexOffset = mp->getFirstVertexIndexOffset(); firstVertexOffset -= deadVtxCount; firstVertexIndexOffset -= deadVtxIdxCount; mp->setFirstVertexOffset( firstVertexOffset ); mp->setFirstVertexIndexOffset( firstVertexIndexOffset ); } } }
CCRange CC3PointParticle::getVertexIndexRange() { return CCRangeMake(m_particleIndex, getVertexIndexCount()); }