Example #1
0
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()); 
}