void Barrier::CreateSelf()
{
	if(m_created) return;
	if(m_Exploded) return;
    
	b2PolygonShape box;
	b2FixtureDef fd;
	b2BodyDef bd;
	box.SetAsBox(0.5f, 1.25f);
	
	fd.shape = &box;
	fd.friction = 0.62f;
	fd.filter.groupIndex = -1;
	fd.isSensor = true;
	
	bd.position.Set(m_StartPos.x, m_StartPos.y+1.25);
	
	m_MainCollision = m_world->CreateBody(&bd);
	m_MainCollision->CreateFixture(&fd);
    
    
	TextureObject *tex = NULL;
    tex = new TextureObject((char*)"ctm_City_Barrier_Small.png",m_ccLayer,2,true,kTexture2DPixelFormat_Default);
    m_MainCollision->SetUserData(tex);
    tex->SetTextureOffset(0.75f, 1.0f);
    
    m_Lights = CCSprite::createWithSpriteFrameName("ctm_City_Barrier_Small_Lights.png");
    //m_Lights->setPosition = ccp(PTM_RATIO*(m_StartPos.x+0.75),PTM_RATIO*(m_StartPos.y+2.5f));
    tex->GetSprite()->addChild(m_Lights,2);
    
    m_Exploded = false;
    m_created = true;
    m_LastFlicker = 0.2f;
    m_waitTime = 0.0f;
}
Beispiel #2
0
void Ramp::CreateSelf()
{
	if(m_created) return;
	
	b2PolygonShape triangle;
	b2FixtureDef fd;
	b2BodyDef bd;
	
	triangle.Set(s_RampDefs[m_Type].points,3);
	
	
	fd.shape = ▵
	fd.friction = 0.62f;
	fd.filter.groupIndex = -1;
	
	bd.position.Set(m_StartPos.x, m_StartPos.y+s_RampDefs[m_Type].yOffset);
	
	m_MainCollision = m_world->CreateBody(&bd);
	m_MainCollision->CreateFixture(&fd);
	TextureObject *tex = new TextureObject(s_RampDefs[m_Type].texturename,m_ccLayer,m_sort,true,kTexture2DPixelFormat_Default);
	tex->SetTextureScale(m_Scale,m_Scale);
	m_MainCollision->SetUserData(tex);
    m_Texture = tex;
    
/*    if(m_Type==WALL_FRONT)
    {
        m_Overlay = [CCSprite spriteWithSpriteFrameName:@"ctm_Wall_frontramp_01_Overlay_Fade.png"];
        [m_frontLayer addChild:m_Overlay z:1];
        m_Overlay.position = ccp(m_MainCollision->GetPosition().x*PTM_RATIO,m_MainCollision->GetPosition().y*PTM_RATIO);
        m_bLeftSide = true;
        m_WallRamp = nil;
    }*/
	
}
void ExplodingBarrel::DestroySelf()
{
	if(m_created)
	{
		TextureObject* texObject = (TextureObject*)m_MainCollision->GetUserData();
		texObject->ReleaseTexture();
		delete texObject;
		m_world->DestroyBody(m_MainCollision);
	}
}
// Creates a new texture given the image file into OpenGL
void TextureCtrlr::CreateNewTexture(GLuint textureUnit, const char* textureFilePath, const char* nameInShader)
{
	// Create new texture object
	TextureObject* newTexture = new TextureObject(textureUnit);
	newTexture->SetNameInShader(nameInShader);
	newTexture->LoadTextureFileIntoOpenGL(textureFilePath);

	// Add new texture to the list
	this->allTextures.push_back(newTexture);
}
void Barrier::DestroySelf()
{
	if(m_created)
	{
		TextureObject* texObject = (TextureObject*)m_MainCollision->GetUserData();
		texObject->ReleaseTexture();
		delete texObject;
		m_world->DestroyBody(m_MainCollision);
        //[m_Lights removeFromParentAndCleanup:YES];
	}
}
// Get the texture's name in the shaders assigned to the texture unit
const char* TextureCtrlr::GetTextureName(GLuint textureUnit)
{
	TextureObject* theTexture = this->FindTextureByUnit(textureUnit);

	if(theTexture == NULL)
	{
		std::cout << "Warning: TextureCtrlr::GetTextureName(): Texture not found!" << std::endl;
		return NULL;
	}

	return theTexture->GetTextureName();
}
// Sets up the texture unit's wrapping and min/mag filters
void TextureCtrlr::SetupTextureProperties(GLuint textureUnit, GLenum wrapping, GLenum filtering)
{
	// Find the texture by given unit
	TextureObject* identfiedTexture = this->FindTextureByUnit(textureUnit);
	
	// Complain if texture not found
	if(identfiedTexture == NULL)
	{
		std::cout << "Warning: TextureCtrlr::SetupTextureProperties(): Texture unit not found!" << std::endl;
		return;
	}

	// Set up properties
	identfiedTexture->SetupProperties(wrapping, filtering);
}
Beispiel #8
0
void Window::TextureDisplayer_SetTextureObject(TextureObject Texture){
    if(TextureDisplayer_Inited){
        //BorrowContext();
        ConsoleEcho("on rentre");
        Texture.Load(0);
        ConsoleEcho("Binding");
        Texture.Bind(1);
        ConsoleEcho("Binded");
        int dara=1;
        float dara2=1.0f;
        TextureDisplayer_Texture=Texture.GetTextureIndex();
        ConsoleEcho("Envoie de la Texture");
        SetUniform(GL_INT,1,&dara,TextureDisplayer_Adress,"Tex1");
        memory_fence();
        SetUniform(GL_FLOAT,1,&dara2,TextureDisplayer_Adress,"ColorTest");
    }
}
Beispiel #9
0
void Ramp::DestroySelf()
{
	if(m_created)
	{
		TextureObject* texObject = (TextureObject*)m_MainCollision->GetUserData();
		texObject->ReleaseTexture();
		delete texObject;
        m_Texture = NULL;
		m_world->DestroyBody(m_MainCollision);
        
/*        if(m_WallRamp)
        {
            [m_WallRamp removeFromParentAndCleanup:YES];
            m_WallRamp = nil;
        }*/
	}
}
void ExplodingBarrel::CreateSelf()
{
	if(m_created) return;
	
	b2PolygonShape box;
	b2FixtureDef fd;
	b2BodyDef bd;
	
	box.SetAsBox(0.8f, 1.0f);
	
	fd.shape = &box;
	fd.friction = 0.62f;
	fd.filter.groupIndex = -1;
	fd.isSensor = true;
	
	bd.position.Set(m_StartPos.x, m_StartPos.y+1.0);
	
	m_MainCollision = m_world->CreateBody(&bd);
	m_MainCollision->CreateFixture(&fd);
	TextureObject *tex = new TextureObject((char*)"ctm_Barrel.png",m_ccLayer,1,true,kTexture2DPixelFormat_Default);
	m_MainCollision->SetUserData(tex);
	tex->SetTextureOffset(0.0f, 0.55);
	m_Exploded = false;
}
Beispiel #11
0
void GlyphTexture::apply(osg::State& state) const
{
    // get the contextID (user defined ID of 0 upwards) for the 
    // current OpenGL context.
    const unsigned int contextID = state.getContextID();

    if (contextID>=_glyphsToSubload.size())
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        // graphics context is beyond the number of glyphsToSubloads, so
        // we must now copy the glyph list across, this is a potential
        // threading issue though is multiple applies are happening the
        // same time on this object - to avoid this condition number of
        // graphics contexts should be set before create text.
        for(unsigned int i=_glyphsToSubload.size();i<=contextID;++i)
        {
            GlyphPtrList& glyphPtrs = _glyphsToSubload[i];
            for(GlyphRefList::const_iterator itr=_glyphs.begin();
                itr!=_glyphs.end();
                ++itr)
            {
                glyphPtrs.push_back(itr->get());
            }
        }
    }


    const Extensions* extensions = getExtensions(contextID,true);
    bool generateMipMapSupported = extensions->isGenerateMipMapSupported();

    // get the texture object for the current contextID.
    TextureObject* textureObject = getTextureObject(contextID);
    
    bool newTextureObject = (textureObject == 0);

    if (newTextureObject)
    {
        GLint maxTextureSize = 256;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
        if (maxTextureSize < getTextureWidth() || maxTextureSize < getTextureHeight())
        {
            OSG_WARN<<"Warning: osgText::Font texture size of ("<<getTextureWidth()<<", "<<getTextureHeight()<<") too large, unable to create font texture."<<std::endl;
            OSG_WARN<<"         Maximum supported by hardward by native OpenGL implementation is ("<<maxTextureSize<<","<<maxTextureSize<<")."<<std::endl;
            OSG_WARN<<"         Please set OSG_MAX_TEXTURE_SIZE lenvironment variable to "<<maxTextureSize<<" and re-run application."<<std::endl;
            return;
        }
        
        // being bound for the first time, need to allocate the texture

        _textureObjectBuffer[contextID] = textureObject = osg::Texture::generateTextureObject(
                this, contextID,GL_TEXTURE_2D,1,GL_ALPHA,getTextureWidth(), getTextureHeight(),1,0);

        textureObject->bind();


        applyTexParameters(GL_TEXTURE_2D,state);

        
        // need to look at generate mip map extension if mip mapping required.
        switch(_min_filter)
        {
        case NEAREST_MIPMAP_NEAREST:
        case NEAREST_MIPMAP_LINEAR:
        case LINEAR_MIPMAP_NEAREST:
        case LINEAR_MIPMAP_LINEAR:
            if (generateMipMapSupported)
            {
                glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
            }
            else glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, LINEAR);
            break;
        default:
            // not mip mapping so no problems.
            break;
        }
        
        unsigned int imageDataSize = getTextureHeight()*getTextureWidth();
        unsigned char* imageData = new unsigned char[imageDataSize];
        for(unsigned int i=0; i<imageDataSize; ++i)
        {
            imageData[i] = 0;
        }
        

        // allocate the texture memory.
        glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA,
                getTextureWidth(), getTextureHeight(), 0,
                GL_ALPHA,
                GL_UNSIGNED_BYTE,
                imageData );
                
        delete [] imageData;
    
    }
    else
    {
        // reuse texture by binding.
        textureObject->bind();
        
        if (getTextureParameterDirty(contextID))
        {
            applyTexParameters(GL_TEXTURE_2D,state);
        }


    }
    
    static const GLubyte* s_renderer = 0;
    static bool s_subloadAllGlyphsTogether = false;
    if (!s_renderer)
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        s_renderer = glGetString(GL_RENDERER);
        OSG_INFO<<"glGetString(GL_RENDERER)=="<<s_renderer<<std::endl;
        if (s_renderer && strstr((const char*)s_renderer,"IMPACT")!=0)
        {
            // we're running on an Octane, so need to work around its
            // subloading bugs by loading all at once.
            s_subloadAllGlyphsTogether = true;
        }
        
        if (s_renderer && 
            ((strstr((const char*)s_renderer,"Radeon")!=0) || 
            (strstr((const char*)s_renderer,"RADEON")!=0) ||
            (strstr((const char*)s_renderer,"ALL-IN-WONDER")!=0)))
        {
            // we're running on an ATI, so need to work around its
            // subloading bugs by loading all at once.
            s_subloadAllGlyphsTogether = true;
        }

        if (s_renderer && strstr((const char*)s_renderer,"Sun")!=0)
        {
            // we're running on an solaris x server, so need to work around its
            // subloading bugs by loading all at once.
            s_subloadAllGlyphsTogether = true;
        }

        const char* str = getenv("OSG_TEXT_INCREMENTAL_SUBLOADING");
        if (str)
        {
            s_subloadAllGlyphsTogether = strcmp(str,"OFF")==0 || strcmp(str,"Off")==0 || strcmp(str,"off")==0;
        }
    }


    // now subload the glyphs that are outstanding for this graphics context.
    GlyphPtrList& glyphsWereSubloading = _glyphsToSubload[contextID];

    if (!glyphsWereSubloading.empty() || newTextureObject)
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        if (!s_subloadAllGlyphsTogether)
        {
            if (newTextureObject)
            {
                for(GlyphRefList::const_iterator itr=_glyphs.begin();
                    itr!=_glyphs.end();
                    ++itr)
                {
                    (*itr)->subload();
                }
            }
            else // just subload the new entries.
            {            
                // default way of subloading as required.
                //std::cout<<"subloading"<<std::endl;
                for(GlyphPtrList::iterator itr=glyphsWereSubloading.begin();
                    itr!=glyphsWereSubloading.end();
                    ++itr)
                {
                    (*itr)->subload();
                }
            }
            
            // clear the list since we have now subloaded them.
            glyphsWereSubloading.clear();
            
        }
        else
        {
            OSG_INFO<<"osgText::Font loading all glyphs as a single subload."<<std::endl;

            // Octane has bugs in OGL driver which mean that subloads smaller
            // than 32x32 produce errors, and also cannot handle general alignment,
            // so to get round this copy all glyphs into a temporary image and
            // then subload the whole lot in one go.

            int tsize = getTextureHeight() * getTextureWidth();
            unsigned char *local_data = new unsigned char[tsize];
            memset( local_data, 0L, tsize);

            for(GlyphRefList::const_iterator itr=_glyphs.begin();
                itr!=_glyphs.end();
                ++itr)
            {
                //(*itr)->subload();

                // Rather than subloading to graphics, we'll write the values
                // of the glyphs into some intermediate data and subload the
                // whole thing at the end
                for( int t = 0; t < (*itr)->t(); t++ )
                {
                    for( int s = 0; s < (*itr)->s(); s++ )
                    {
                        int sindex = (t*(*itr)->s()+s);
                        int dindex =  
                            ((((*itr)->getTexturePositionY()+t) * getTextureWidth()) +
                            ((*itr)->getTexturePositionX()+s));

                        const unsigned char *sptr = &(*itr)->data()[sindex];
                        unsigned char *dptr       = &local_data[dindex];

                        (*dptr)   = (*sptr);
                    }
                }
            }

            // clear the list since we have now subloaded them.
            glyphsWereSubloading.clear();

            // Subload the image once
            glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 
                    getTextureWidth(),
                    getTextureHeight(),
                    GL_ALPHA, GL_UNSIGNED_BYTE, local_data );

            delete [] local_data;

        }
    }
    else
    {
//        OSG_INFO << "no need to subload "<<std::endl;
    }



//     if (generateMipMapTurnedOn)
//     {
//         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
//     }


}
void 
SparseTexture2DArray::apply( osg::State& state ) const
{
    // get the contextID (user defined ID of 0 upwards) for the 
    // current OpenGL context.
    const unsigned int contextID = state.getContextID();

    Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
    //ElapsedTime elapsedTime(&(tom->getApplyTime()));
    tom->getNumberApplied()++;

    const Extensions* extensions = getExtensions(contextID,true);

    // if not supported, then return
    if (!extensions->isTexture2DArraySupported() || !extensions->isTexture3DSupported())
    {
        OSG_WARN<<"Warning: Texture2DArray::apply(..) failed, 2D texture arrays are not support by OpenGL driver."<<std::endl;
        return;
    }

    // get the texture object for the current contextID.
    TextureObject* textureObject = getTextureObject(contextID);

    if (textureObject && _textureDepth>0)
    {
        const osg::Image* image = firstValidImage();
        if (image && getModifiedCount(0, contextID) != image->getModifiedCount())
        {
            // compute the internal texture format, this set the _internalFormat to an appropriate value.
            computeInternalFormat();

            GLsizei new_width, new_height, new_numMipmapLevels;

            // compute the dimensions of the texture.
            computeRequiredTextureDimensions(state, *image, new_width, new_height, new_numMipmapLevels);

            if (!textureObject->match(GL_TEXTURE_2D_ARRAY_EXT, new_numMipmapLevels, _internalFormat, new_width, new_height, 1, _borderWidth))
            {
                Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
                _textureObjectBuffer[contextID] = 0;
                textureObject = 0;
            }
        }
    }

    // if we already have an texture object, then 
    if (textureObject)
    {
        // bind texture object
        textureObject->bind();

        // if texture parameters changed, then reset them
        if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);

        // if subload is specified, then use it to subload the images to GPU memory
        //if (_subloadCallback.valid())
        //{
        //    _subloadCallback->subload(*this,state);
        //}
        //else
        {
            // for each image of the texture array do
            for (GLsizei n=0; n < _textureDepth; n++)
            {
                osg::Image* image = _images[n].get();

                // if image content is modified, then upload it to the GPU memory
                // GW: this means we have to "dirty" an image before setting it!
                if (image && getModifiedCount(n,contextID) != image->getModifiedCount())
                {
                    applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _internalFormat, _numMipmapLevels);
                    getModifiedCount(n,contextID) = image->getModifiedCount();
                }
            }
        }
    }

    // nothing before, but we have valid images, so do manual upload and create texture object manually
    else if ( firstValidImage() != 0L ) // if (imagesValid())
    {
        // compute the internal texture format, this set the _internalFormat to an appropriate value.
        computeInternalFormat();

        // compute the dimensions of the texture.
        osg::Image* firstImage = firstValidImage();
        computeRequiredTextureDimensions(state, *firstImage, _textureWidth, _textureHeight, _numMipmapLevels);

        // create texture object
        textureObject = generateTextureObject(
            this, contextID,GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);

        // bind texture
        textureObject->bind();
        applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT, state);

        _textureObjectBuffer[contextID] = textureObject;

        // First we need to allocate the texture memory
        int sourceFormat = _sourceFormat ? _sourceFormat : _internalFormat;

        if( isCompressedInternalFormat( sourceFormat ) && 
            sourceFormat == _internalFormat &&
            extensions->isCompressedTexImage3DSupported() )
        {
            extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
                _textureWidth, _textureHeight, _textureDepth, _borderWidth,
                firstImage->getImageSizeInBytes() * _textureDepth,
                0);
        }
        else
        {   
            // Override compressed source format with safe GL_RGBA value which not generate error
            // We can safely do this as source format is not important when source data is NULL
            if( isCompressedInternalFormat( sourceFormat ) )
                sourceFormat = GL_RGBA;

            extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
                _textureWidth, _textureHeight, _textureDepth, _borderWidth,
                sourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
                0); 
        }

        // For certain we have to manually allocate memory for mipmaps if images are compressed
        // if not allocated OpenGL will produce errors on mipmap upload.
        // I have not tested if this is neccessary for plain texture formats but 
        // common sense suggests its required as well.
        if( _min_filter != LINEAR && _min_filter != NEAREST && firstImage->isMipmap() )
            allocateMipmap( state );

        // now for each layer we upload it into the memory
        for (GLsizei n=0; n<_textureDepth; n++)
        {
            // if image is valid then upload it to the texture memory
            osg::Image* image = _images[n].get();
            if (image)
            {
                // now load the image data into the memory, this will also check if image do have valid properties
                applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _internalFormat, _numMipmapLevels);
                getModifiedCount(n,contextID) = image->getModifiedCount();
            }
        }

        const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
        // source images have no mipmamps but we could generate them...  
        if( _min_filter != LINEAR && _min_filter != NEAREST && !firstImage->isMipmap() &&  
            _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported() )
        {
            _numMipmapLevels = osg::Image::computeNumberOfMipmapLevels( _textureWidth, _textureHeight );
            generateMipmap( state );
        }

        textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);

        // unref image data?
        if (isSafeToUnrefImageData(state))
        {
            SparseTexture2DArray* non_const_this = const_cast<SparseTexture2DArray*>(this);
            for (int n=0; n<_textureDepth; n++)
            {                
                if (_images[n].valid() && _images[n]->getDataVariance()==STATIC)
                {
                    non_const_this->_images[n] = NULL;
                }
            }
        }

    }

    // No images present, but dimensions are set. So create empty texture
    else if ( (_textureWidth > 0) && (_textureHeight > 0) && (_textureDepth > 0) && (_internalFormat!=0) )
    {
        // generate texture 
        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(
            this, contextID, GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);

        textureObject->bind();
        applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);

        extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
            _textureWidth, _textureHeight, _textureDepth,
            _borderWidth,
            _sourceFormat ? _sourceFormat : _internalFormat,
            _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
            0); 

    }

    // nothing before, so just unbind the texture target
    else
    {
        glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, 0 );
    }

    // if texture object is now valid and we have to allocate mipmap levels, then
    if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
    {
        generateMipmap(state);
    }
}
Beispiel #13
0
void ShaderObject::setUniformTexture( const std::string& name, const TextureObject& textureObject) {
	const GLuint location = glGetUniformLocation( id, name.c_str() );
	assert( isValidUniform( name, location ) );
	glUniform1i( location, textureObject.getUnitID() );
}
bool Barrier::HandleBeginContact(b2Fixture *fixtureA,b2Fixture *fixtureB)
{
	if(!m_created) return false;
	if(m_Exploded) return false;
	
	b2Fixture *myFixture = m_MainCollision->GetFixtureList();
	if(myFixture == fixtureA || myFixture == fixtureB)
	{
        if(myFixture == fixtureA && fixtureB->GetFilterData().categoryBits == 0x7fff)
        {
            b2Vec2 impulse = -fixtureB->GetBody()->GetLinearVelocity();
            impulse.y = RandomFloat(2.0f,10.0f);
            impulse *= fixtureB->GetBody()->GetMass()*1.5f;
            fixtureB->GetBody()->ApplyLinearImpulse(impulse,fixtureB->GetBody()->GetWorldCenter());
                        
            if(fixtureB->GetBody()->GetAngularVelocity()<0.0f)
                fixtureB->GetBody()->ApplyTorque(RandomFloat(30000.0f,35000.0f));
            else
                fixtureB->GetBody()->ApplyTorque(RandomFloat(-35000.0f,-30000.0f));
        }
        else if(myFixture == fixtureB && fixtureA->GetFilterData().categoryBits == 0x7fff)
        {
            b2Vec2 impulse = -fixtureA->GetBody()->GetLinearVelocity();
            impulse.y = RandomFloat(2.0f,10.0f);
            impulse *= fixtureA->GetBody()->GetMass()*1.5f;
            fixtureA->GetBody()->ApplyLinearImpulse(impulse,fixtureA->GetBody()->GetWorldCenter());
            
            if(fixtureA->GetBody()->GetAngularVelocity()<0.0f)
                fixtureA->GetBody()->ApplyTorque(RandomFloat(30000.0f,35000.0f));
            else
                fixtureA->GetBody()->ApplyTorque(RandomFloat(-35000.0f,-30000.0f));
        }
        else if(m_waitTime<=0.0f)
        {
            if(RandomInt(0,100)>50)
                Rider::g_MainBody->ApplyTorque(RandomFloat(40000.0f,50000.0f));
            else
                Rider::g_MainBody->ApplyTorque(RandomFloat(-50000.0f,-40000.0f));
            
            
            if(m_unbreakable)
            {
                Rider::g_LauchDir.y = 1.0f;
                Rider::g_LauchDir.x = Rider::g_MainBody->GetLinearVelocity().x>0.0f?-40.0f:40.0f;
                Rider::g_BikeAudio->PushState(BikeAudio::ROUGH);
            }
            else
            {
                Rider::g_LauchDir.y = 10.0f;
                Rider::g_LauchDir.x = -Rider::g_MainBody->GetLinearVelocity().x/1.1f;
            }
            Rider::g_DoLaunch = true;
            //m_waitTime = 0.5f;
        }
        AudioManager::PlayEffect(AUDIO_BIKE_HARD_IMPACT);
        
        if(!m_unbreakable)
        {
            m_Exploded = true;
            TextureObject* texObject = (TextureObject*)m_MainCollision->GetUserData();
            texObject->GetSprite()->setVisible(false);
            //m_Lights.visible = NO;
        }
		return false;
	}
	return false;
}
bool ExplodingBarrel::HandleBeginContact(b2Fixture *fixtureA,b2Fixture *fixtureB)
{
	if(!m_created) return false;
	if(m_Exploded) return false;
	
	b2Fixture *myFixture = m_MainCollision->GetFixtureList();
	if(myFixture == fixtureA || myFixture == fixtureB)
	{
        if(myFixture == fixtureA && fixtureB->GetFilterData().categoryBits == 0x7fff)
            return false;
        if(myFixture == fixtureB && fixtureA->GetFilterData().categoryBits == 0x7fff)
            return false;
        
		if(!Rider::g_isCrashed)
		{
			Rider::g_LauchDir.x = RandomFloat(-20.0f,20.0f);
			Rider::g_MainBody->ApplyTorque(RandomFloat(40000.0f,50000.0f));
			Rider::g_LauchDir.y = 50.0f;
			Rider::g_DoLaunch = true;
			Rider::g_ForceCrash = 0.2f;
            Level::ScreenShake(0.5f,10.0f,10.0f);
            Monkey::s_RandomXVel = 10.0f;
            Monkey::s_RandomYVel = 10.0f;
		}
        else
        {
            Level::ScreenShake(0.5f,10.0f,10.0f);
            Monkey::s_RandomXVel = 10.0f;
            Monkey::s_RandomYVel = 10.0f;

            b2Body *other = NULL;
            
            if(myFixture == fixtureA)
                other = fixtureB->GetBody();
            if(myFixture == fixtureB)
                other = fixtureA->GetBody();
            
            b2Vec2 away = Monkey::getMonkey()->getCenter()-myFixture->GetBody()->GetPosition();
            float length = away.Normalize();
            if(length<5.0f || other->GetFixtureList()->GetFilterData().categoryBits == 0x0004)
            {
                away *= 35.0f;
                Monkey::getMonkey()->SetVelocity(away);
            }
            away = DirtBike::s_Cart->GetPosition()-myFixture->GetBody()->GetPosition();
            length = away.Normalize();
            if(length<4.0f || other == DirtBike::s_Cart)
            {
                away *= 35.0f;
                DirtBike::s_Cart->SetLinearVelocity(away);
            }
            away = DirtBike::s_Wheel1->GetPosition()-myFixture->GetBody()->GetPosition();
            length = away.Normalize();
            if(length<4.0f || other == DirtBike::s_Wheel1)
            {
                away *= 35.0f;
                DirtBike::s_Wheel1->SetLinearVelocity(away);
            }
            away = DirtBike::s_Wheel2->GetPosition()-myFixture->GetBody()->GetPosition();
            length = away.Normalize();
            if(length<4.0f || other == DirtBike::s_Wheel2)
            {
                away *= 35.0f;
                DirtBike::s_Wheel2->SetLinearVelocity(away);
            }
            
        }
        //Rider::g_OnFire = 5.0f;
		createBarrelExplosion(m_ccLayer->getParent(),m_StartPos.x*PTM_RATIO,m_StartPos.y*PTM_RATIO);
		//createExplosion([m_ccLayer parent],m_StartPos.x*PTM_RATIO,m_StartPos.y*PTM_RATIO);
		
		TextureObject* texObject = (TextureObject*)m_MainCollision->GetUserData();
		texObject->GetSprite()->setVisible(false);
		m_Exploded = true;
		return false;
	}
	return false;
}