コード例 #1
0
void CC3VertexTextureCoordinates::alignWithTextureCoverage( const CCSize& texCoverage )
{
	CCAssert((texCoverage.width && texCoverage.height), "CC3VertexTextureCoordinates mapsize cannot have zero dimension");

	// Don't waste time adjusting if nothing is changing
	// (eg. POT textures, or new texture has same texture map as old).
	if (texCoverage.equals(m_mapSize)) 
		return;
	
	CC3_TRACE( "[vtx]CC3VertexTextureCoordinates aligning and changing map size from %s to %s but not flipping vertically", 
		stringFromCCSize(m_mapSize).c_str(), stringFromCCSize(texCoverage).c_str() );

	// The scale factor
	CCSize mapRatio = CCSizeMake(texCoverage.width / m_mapSize.width, texCoverage.height / m_mapSize.height);
	
	// The amount by which to translate the image vertically
	GLfloat currVertXln = 1.0f - m_mapSize.height;
	GLfloat newVertXln = 1.0f - texCoverage.height;
	
	for (GLuint i = 0; i < m_vertexCount; i++) 
	{
		ccTex2F* ptc = (ccTex2F*)getAddressOfElement(i);
		ptc->u *= mapRatio.width;
		ptc->v = (ptc->v - currVertXln) * mapRatio.height + newVertXln;
	}
	m_mapSize = texCoverage;	// Remember what we've set the map size to

	updateGLBuffer();
}
コード例 #2
0
/**
 * If the particle system has exhausted and it is set to auto-remove, remove this
 * node from the scene so that this node and the particle system will be released.
 */
void CC3ParticleSystemBillboard::updateBeforeTransform( CC3NodeUpdatingVisitor* visitor )
{
	if ( m_pBillboard ) 
	{
		CCParticleSystem* ps = (CCParticleSystem*)m_pBillboard;
		if ( ps->isAutoRemoveOnFinish() && !ps->isActive() && ps->getParticleCount() == 0 )
		{
			CC3_TRACE("[bbd]2D particle system exhausted. Removing");
			visitor->requestRemovalOf( this );
		}
	}
}
コード例 #3
0
void CC3MeshParticleEmitter::transformParticles()
{
	GLuint partCount = getParticleCount();
	CC3_TRACE("CC3MeshParticleEmitter transforming %d particles", m_particleCount);

	for (GLuint partIdx = 0; partIdx < partCount; partIdx++) 
	{
		CC3MeshParticle* mp = (CC3MeshParticle*)m_particles->objectAtIndex( partIdx );
		mp->transformVertices();
	}

	m_isParticleTransformDirty = false;
}
コード例 #4
0
GLenum GLMagnifyingFunctionFromETextureFilter(GLuint eTextureFilter) 
{
	switch (eTextureFilter) 
	{
		case eFilter_Nearest:
			return GL_NEAREST;
		case eFilter_Linear:
			return GL_LINEAR;
		default:
			CC3_TRACE("Unknown ETextureFilter '%s'", NSStringFromETextureFilter(eTextureFilter).c_str());
			return GL_LINEAR;
	}
}
コード例 #5
0
GLenum GLTextureWrapFromETextureWrap(GLuint eTextureWrap) 
{
	switch (eTextureWrap) 
	{
		case eWrap_Clamp:
			return GL_CLAMP_TO_EDGE;
		case eWrap_Repeat:
			return GL_REPEAT;
		default:
			CC3_TRACE("Unknown ETextureWrap '%s'", NSStringFromETextureWrap(eTextureWrap).c_str());
			return GL_REPEAT;
	}
}
コード例 #6
0
void CC3VertexTextureCoordinates::alignWithInvertedTextureCoverage( const CCSize& texCoverage )
{
	CCAssert((texCoverage.width && texCoverage.height), "CC3VertexTextureCoordinates mapsize %s cannot have zero dimension"/*,
			  stringFromCCSize(texCoverage).c_str()*/);
	CC3_TRACE( "[vtx]CC3VertexTextureCoordinates aligning and changing map size from %s to %s and flipping vertically", 
		stringFromCCSize(m_mapSize).c_str(), stringFromCCSize(texCoverage).c_str() );
	
	CCSize mapRatio = CCSizeMake(texCoverage.width / m_mapSize.width, texCoverage.height / m_mapSize.height);
	
	for (GLuint i = 0; i < m_vertexCount; i++) 
	{
		ccTex2F* ptc = (ccTex2F*)getAddressOfElement( i );
		ptc->u *= mapRatio.width;
		ptc->v = texCoverage.height - (ptc->v * mapRatio.height);
	}

	// Remember that we've flipped and what we've set the map size to
	m_mapSize = texCoverage;
	m_expectsVerticallyFlippedTextures = !m_expectsVerticallyFlippedTextures;
	
	updateGLBuffer();
	CC3_TRACE("[vtx]CC3VertexTextureCoordinates aligned and flipped vertically");
}
コード例 #7
0
void CC3GLSLUniform::setIntVector4( const CC3IntVector4& value, GLuint index )
{
	CCAssert((GLint)index < _size, "CC3GLSLUniform could not set value because index %d is out of bounds"/*, index*/);
	
	switch (_type) 
	{		
		case GL_FLOAT:
		case GL_FLOAT_VEC2:
		case GL_FLOAT_VEC3:
		case GL_FLOAT_VEC4:
		case GL_FLOAT_MAT2:
			setVector4( CC3Vector4((GLfloat)value.x, (GLfloat)value.y, (GLfloat)value.z, (GLfloat)value.w), index );
			return;
			
		case GL_FLOAT_MAT3:
		case GL_FLOAT_MAT4:
			CCAssert(false, "CC3GLSLUniform attempted to set scalar or vector when matrix type %s expected."/*,
					 stringFromGLEnum(_type).c_str()*/);
			return;
			
		case GL_INT:
		case GL_BOOL:
		case GL_SAMPLER_2D:
		case GL_SAMPLER_CUBE:
			((GLint*)m_varValue)[index] = *(GLint*)&value;
			return;
		case GL_INT_VEC2:
		case GL_BOOL_VEC2:
			((CC3IntPoint*)m_varValue)[index] = *(CC3IntPoint*)&value;
			return;
		case GL_INT_VEC3:
		case GL_BOOL_VEC3:
			((CC3IntVector*)m_varValue)[index] = *(CC3IntVector*)&value;
			return;
		case GL_INT_VEC4:
		case GL_BOOL_VEC4:
			((CC3IntVector4*)m_varValue)[index] = value;
			return;
			
		default:
			CCAssert(false, "CC3GLSLUniform could not set value because type %s is not understood"/*,
					  stringFromGLEnum(_type).c_str()*/);
			return;
	}
	CC3_TRACE("CC3GLSLUniform setting value to (%d, %d, %d, %d)", value.x, value.y, value.z, value.w);
}
コード例 #8
0
ファイル: CC3Cache.cpp プロジェクト: ClAndHHL/cocos3d-x
void CC3Cache::addObject( CC3Cacheable* obj )
{
	if ( !obj ) 
		return;
		
	std::string objName = obj->getName();
	CCAssert(!objName.empty(), "obj cannot be added to the cache because its name property is nil.");

	if ( getObjectNamed( objName ) )
		return;
	
	CC3Cacheable* wrap = obj;
	
	_objectsByName->setObject( wrap, objName );
		
	CC3_TRACE("[rez]Added obj[%s] to the %s cache.", objName.c_str(), _typeName.c_str());
}
コード例 #9
0
/** Update the particles after the transform, and then update the mesh node.  */
void CC3ParticleEmitter::processUpdateAfterTransform( CC3NodeUpdatingVisitor* visitor )
{
	// If configured to update particles after the node is transformed, do so here.
	// For each particle, invoke the updateBeforeTransform: method. 
	// Particles can also be removed during the update process.
	if ( m_shouldUpdateParticlesAfterTransform )
		updateParticlesAfterTransform( visitor );
	
	// If emission has stopped and all the particles have been killed off and the
	// emitter should be removed when finished, remove the emitter from its parent.
	if ( isFinished() && shouldRemoveOnFinish() ) 
	{
		CC3_TRACE("[ptc]CC3ParticleEmitter is exhausted and is being removed");
		visitor->requestRemovalOf( this );
	}
	
	super::processUpdateAfterTransform( visitor );
}
コード例 #10
0
void CC3MeshParticleEmitter::setParticleTemplateMesh( CC3Mesh* aMesh )
{
	if (aMesh == m_pParticleTemplateMesh) 
		return;
	
	CC_SAFE_RELEASE( m_pParticleTemplateMesh );
	m_pParticleTemplateMesh = aMesh;
	CC_SAFE_RETAIN( aMesh );

	// Add vertex content if not already set, and align the drawing mode
	if ( getVertexContentTypes() == kCC3VertexContentNone )
		setVertexContentTypes( aMesh->getVertexContentTypes() );

	setDrawingMode( aMesh->getDrawingMode() );

	CC3_TRACE( "[ptc]Particle template mesh of CC3MeshParticleEmitter set to %s drawing %s with %d vertices and %d vertex indices",
			 aMesh->fullDescription().c_str(), stringFromGLEnum(getDrawingMode()).c_str(),
			 aMesh->getVertexCount(), aMesh->getVertexIndexCount() );
}
コード例 #11
0
/**
 * For each particle, invoke the updateAfterTransform: method.
 * If the particle has expired, remove it from the particles array.
 */
void CC3ParticleEmitter::updateParticlesAfterTransform( CC3NodeUpdatingVisitor* visitor )
{
	GLuint i = 0;
	while ( i < m_particleCount ) 
	{
		CC3Particle* p = (CC3Particle*)m_particles->objectAtIndex( i );
		p->updateAfterTransform( visitor );
		
		if (p->isAlive())
		{
			i++;			// Move on to next particle
		}
		else
		{
			// Remove the particle from active use and don't increment iterator.
			CC3_TRACE("[ptc]Expiring %s", p->fullDescription().c_str());
			finalizeAndRemoveParticle( p, i );
		}
	}
}
コード例 #12
0
/**
 * Returns a 4D directional vector which can be added to each vertex when creating
 * the shadow volume vertices from the corresponding shadow caster vertices.
 *
 * The returned vector is in the local coordinate system of the shadow caster.
 *
 * The returned directional vector is a small offset vector in the direction away
 * from the light. A unit vector in that direction is scaled by both the distance
 * from the center of the shadow casting node to the camera and the
 * shadowVolumeVertexOffsetFactor property. Hence, if the shadow caster is farther
 * away from the camera, the returned value will be larger, to reduce the chance
 * of Z-fighting between the faces of the shadow volume and the shadow caster.
 */
CC3Vector4 CC3ShadowVolumeMeshNode::getShadowVolumeVertexOffsetForLightAt( const CC3Vector4& localLightPos )
{
	CC3Vector scLoc = getShadowCaster()->getLocalContentCenterOfGeometry();
	CC3Vector lgtLoc = localLightPos.cc3Vector();
	CC3Vector camLoc = getShadowCaster()->getGlobalTransformMatrixInverted()->transformLocation( getActiveCamera()->getGlobalLocation() );	

	// Get a unit offset vector in the direction away from the light
	CC3Vector offsetDir = (_light->isDirectionalOnly()
												? lgtLoc.negate() 
												: scLoc.difference( lgtLoc )).normalize();

	// Get the distance from the shadow caster CoG and the camera, and scale the
	// unit offset vector by that distance and the shadowVolumeVertexOffsetFactor
	GLfloat camDist = scLoc.distance( camLoc );
	CC3Vector offset = offsetDir.scaleUniform( camDist * _shadowVolumeVertexOffsetFactor );
	CC3_TRACE("CC3ShadowVolumeMeshNode nudging vertices by %s", offset.stringfy().c_str());

	// Create and return a 4D directional vector from the offset
	return CC3Vector4().fromDirection(offset);
}
コード例 #13
0
ファイル: CC3Cache.cpp プロジェクト: HerdiandKun/cocos3d-x
void CC3Cache::addObject( CC3Cacheable* obj )
{
	if ( !obj ) 
		return;
		
	std::string objName = obj->getName();
	CCAssert(!objName.empty(), "obj cannot be added to the cache because its name property is nil.");

	CC3Cacheable* cached = getObjectNamed( objName );
	if ( cached == obj )
		return;
	
	if ( cached != NULL )
	{
		CC3_WARNING( "Duplicated objects 0x%04x and 0x%04x with the same name %s found", (unsigned long long)obj, 
			(unsigned long long)cached, objName.c_str() );
	}

	m_objectsByName->setObject( obj, objName );
		
	CC3_TRACE("[rez]Added obj[%s] to the %s cache.", objName.c_str(), m_typeName.c_str());
}
コード例 #14
0
ファイル: CC3Resource.cpp プロジェクト: HerdiandKun/cocos3d-x
bool CC3Resource::loadFromFile( const std::string& filePath )
{
    if (m_wasLoaded)
    {
        CC3_TRACE("[rez]CC3Resource[%s] has already been loaded.", filePath.c_str());
        return m_wasLoaded;
    }

    // Resolve an absolute path in either the application bundle resource
    // directory or the Cocos3D bundle resource directory.
    std::string absFilePath = filePath;

    if ( absFilePath.empty() )
    {
        CC3_TRACE( "[rez]Could not locate resource file '%s' in either the application resources or the Cocos3D library resources", filePath.c_str() );
        return false;
    }

    CC3_TRACE("[rez]--------------------------------------------------");
    CC3_TRACE("[rez]Loading resource from file '%s'", absFilePath.c_str());

    if ( m_sName.c_str() )
        setName( resourceNameFromFilePath( absFilePath ) );

    if ( m_directory.empty() )
    {
        std::string sDir = CC3String::getDirectory( absFilePath );
        setDirectory( sDir );
    }

    m_wasLoaded = processFile( absFilePath );	// Main subclass loading method

    if (!m_wasLoaded)
    {
        CC3_TRACE("[rez]Could not load resource file '%s'", absFilePath.c_str());
    }

    CC3_TRACE("");		// Empty line to separate from next logs

    return m_wasLoaded;
}
コード例 #15
0
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 );
		}
	}
}