//////////////////////////////////////////////////////////////////////////
// update
//virtual
void GaSpeechBubbleComponent::update( BcF32 Tick )
{
	Super::update( Tick );

	if ( !FontComponent_.isValid() )
	{
		Canvas_ = ParentEntity_->getComponentAnyParentByType< ScnCanvasComponent >();
		FontComponent_ = ParentEntity_->getComponentAnyParentByType< ScnFontComponent >();
	}
	if ( !SpeechBubble_.isValid() )
	{
		SpeechBubble_ = ParentEntity_->getComponentByType<ScnSpriteComponent>( BcName( "SpeechBubbleComponent", 0 ) );
	}
	if ( SpeechBubble_.isValid() )
	{
		SpeechBubble_->setColour( RsColour( 1, 1, 1, Visible_ ? 0.8 : 0 ) );
	}
	if ( !TargetEntity_.isValid() )
	{
		// We aren't even gonna bother
		return;
	}

	MaMat4d TextScaleMatrix;
	//TextScaleMatrix.scale( MaVec4d( 0.04f, 0.04f, 1.0f, 1.0f ) );
	TextScaleMatrix.scale( MaVec4d( 1.00f, -1.00f, 1.0f, 1.0f ) );

	FontComponent_->setAlphaTestStepping( MaVec2d( 0.4f, 0.45f ) );


	if (Visible_)
	{
		TimeBeenVisible_ += Tick;
		if ( TimeBeenVisible_ > VisibleTime_ )
			Visible_ = false;
		//MaMat4d Matrix = getParentEntity()->getWorldMatrix();
		//Matrix = Canvas_->popMatrix();
		Canvas_->pushMatrix( TextScaleMatrix );
	
		MaVec2d Size;
		MaVec3d worldPos = TargetEntity_->getWorldPosition();
		MaVec2d Position( 0 , 0 );
		MaVec2d localPos  = SpeechBubble_->getPosition();
		localPos  = MaVec2d(TargetEntity_->getWorldPosition().x(), -TargetEntity_->getWorldPosition().y() ) + FontOffset_;
		SpeechBubble_->setPosition( MaVec2d( TargetEntity_->getWorldPosition().x(), TargetEntity_->getWorldPosition().y() )  + SpriteOffset_ );
		for( BcU32 Idx = 0; Idx < Text_.size(); ++Idx )
		{
			const auto& Option( Text_[ Idx ] );
			const auto Colour = RsColour::BLACK;
			Size = FontComponent_->drawCentered( Canvas_, localPos + Position, Text_[ Idx ] , Colour, 280 );
			Position += MaVec2d( 0.0f, Size.y() );
		}



		Canvas_->popMatrix();
	}
	//Canvas_->pushMatrix( Matrix );
	//Canvas_->setMatrix( Matrix );
}
Example #2
0
//////////////////////////////////////////////////////////////////////////
// drawLineBox
void ScnCanvasComponent::drawLineBox( const MaVec2d& CornerA, const MaVec2d& CornerB, const RsColour& Colour, BcU32 Layer )
{
	// SLOW.
	drawLine( MaVec2d( CornerA.x(), CornerA.y() ), MaVec2d( CornerB.x(), CornerA.y() ), Colour, Layer );
	drawLine( MaVec2d( CornerB.x(), CornerA.y() ), MaVec2d( CornerB.x(), CornerB.y() ), Colour, Layer );
	drawLine( MaVec2d( CornerB.x(), CornerB.y() ), MaVec2d( CornerA.x(), CornerB.y() ), Colour, Layer );
	drawLine( MaVec2d( CornerA.x(), CornerB.y() ), MaVec2d( CornerA.x(), CornerA.y() ), Colour, Layer );
}
Example #3
0
//////////////////////////////////////////////////////////////////////////
// getScreenPosition
MaVec2d ScnViewComponent::getScreenPosition( const MaVec3d& WorldPosition ) const
{
	MaVec4d ScreenSpace = MaVec4d( WorldPosition, 1.0f ) * ViewUniformBlock_.ClipTransform_;
	MaVec2d ScreenPosition = MaVec2d( ScreenSpace.x() / ScreenSpace.w(), -ScreenSpace.y() / ScreenSpace.w() );

	BcF32 HalfW = BcF32( Viewport_.width() ) * 0.5f;
	BcF32 HalfH = BcF32( Viewport_.height() ) * 0.5f;
	return MaVec2d( ( ScreenPosition.x() * HalfW ), ( ScreenPosition.y() * HalfH ) );
}
Example #4
0
//////////////////////////////////////////////////////////////////////////
// drawBox
void ScnCanvasComponent::drawBox( const MaVec2d& CornerA, const MaVec2d& CornerB, const RsColour& Colour, BcU32 Layer )
{
	ScnCanvasComponentVertex* pVertices = allocVertices( 4 );
	ScnCanvasComponentVertex* pFirstVertex = pVertices;
	
	// Only draw if we can allocate vertices.
	if( pVertices != NULL )
	{
		// Now copy in data.
		BcU32 ABGR = Colour.asABGR();
		
		pVertices->X_ = CornerA.x();
		pVertices->Y_ = CornerA.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = 0.0f;
		pVertices->V_ = 0.0f;
		pVertices->ABGR_ = ABGR;
		++pVertices;

		pVertices->X_ = CornerB.x();
		pVertices->Y_ = CornerA.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = 1.0f;
		pVertices->V_ = 0.0f;
		pVertices->ABGR_ = ABGR;
		++pVertices;

		pVertices->X_ = CornerA.x();
		pVertices->Y_ = CornerB.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = 0.0f;
		pVertices->V_ = 1.0f;
		pVertices->ABGR_ = ABGR;
		++pVertices;

		pVertices->X_ = CornerB.x();
		pVertices->Y_ = CornerB.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = 1.0f;
		pVertices->V_ = 1.0f;
		pVertices->ABGR_ = ABGR;
		
		// Add primitive.	
		addPrimitive( RsTopologyType::TRIANGLE_STRIP, pFirstVertex, 4, Layer, BcTrue );
	}
}
Example #5
0
//////////////////////////////////////////////////////////////////////////
// getWorldPosition
void ScnViewComponent::getWorldPosition( const MaVec2d& ScreenPosition, MaVec3d& Near, MaVec3d& Far ) const
{
	// TODO: Take normalised screen coordinates.
	MaVec2d Screen = ScreenPosition - MaVec2d( static_cast<BcF32>( Viewport_.x() ), static_cast<BcF32>( Viewport_.y() ) );
	const MaVec2d RealScreen( ( Screen.x() / Viewport_.width() ) * 2.0f - 1.0f, ( Screen.y() / Viewport_.height() ) * 2.0f - 1.0f );

	Near.set( RealScreen.x(), -RealScreen.y(), 0.0f );
	Far.set( RealScreen.x(), -RealScreen.y(), 1.0f );

	Near = Near * ViewUniformBlock_.InverseProjectionTransform_;
	Far = Far * ViewUniformBlock_.InverseProjectionTransform_;

	if( ViewUniformBlock_.ProjectionTransform_[3][3] == 0.0f )
	{
		Near *= Viewport_.zNear();
		Far *= Viewport_.zFar();
	}

	Near = Near * ViewUniformBlock_.InverseViewTransform_;
	Far = Far * ViewUniformBlock_.InverseViewTransform_;
}
Example #6
0
//////////////////////////////////////////////////////////////////////////
// drawSprite
void ScnCanvasComponent::drawSprite( const MaVec2d& Position, const MaVec2d& Size, BcU32 TextureIdx, const RsColour& Colour, BcU32 Layer )
{
	ScnCanvasComponentVertex* pVertices = allocVertices( 6 );
	ScnCanvasComponentVertex* pFirstVertex = pVertices;
	
	const MaVec2d CornerA = Position;
	const MaVec2d CornerB = Position + Size;

	const ScnRect Rect = DiffuseTexture_.isValid() ? DiffuseTexture_->getRect( TextureIdx ) : ScnRect();
	
	// Only draw if we can allocate vertices.
	if( pVertices != NULL )
	{
		// Now copy in data.
		BcU32 ABGR = Colour.asABGR();
		
		pVertices->X_ = CornerA.x();
		pVertices->Y_ = CornerA.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = Rect.X_;
		pVertices->V_ = Rect.Y_;
		pVertices->ABGR_ = ABGR;
		++pVertices;
		
		pVertices->X_ = CornerB.x();
		pVertices->Y_ = CornerA.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = Rect.X_ + Rect.W_;
		pVertices->V_ = Rect.Y_;
		pVertices->ABGR_ = ABGR;
		++pVertices;
		
		pVertices->X_ = CornerA.x();
		pVertices->Y_ = CornerB.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = Rect.X_;
		pVertices->V_ = Rect.Y_ + Rect.H_;
		pVertices->ABGR_ = ABGR;
		++pVertices;
		
		pVertices->X_ = CornerA.x();
		pVertices->Y_ = CornerB.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = Rect.X_;
		pVertices->V_ = Rect.Y_ + Rect.H_;
		pVertices->ABGR_ = ABGR;
		++pVertices;

		pVertices->X_ = CornerB.x();
		pVertices->Y_ = CornerA.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = Rect.X_ + Rect.W_;
		pVertices->V_ = Rect.Y_;
		pVertices->ABGR_ = ABGR;
		++pVertices;

		pVertices->X_ = CornerB.x();
		pVertices->Y_ = CornerB.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->U_ = Rect.X_ + Rect.W_;
		pVertices->V_ = Rect.Y_ + Rect.H_;
		pVertices->ABGR_ = ABGR;
		
		// Quickly check last primitive.
		BcBool AddNewPrimitive = BcTrue;
		if( LastPrimitiveSection_ != BcErrorCode )
		{
			ScnCanvasComponentPrimitiveSection& PrimitiveSection = PrimitiveSectionList_[ LastPrimitiveSection_ ];

			// If the last primitive was the same type as ours we can append to it.
			// NOTE: Need more checks here later.
			if( PrimitiveSection.Type_ == RsTopologyType::TRIANGLE_LIST &&
				PrimitiveSection.Layer_ == Layer &&
				PrimitiveSection.MaterialComponent_ == MaterialComponent_ )
			{
				PrimitiveSection.NoofVertices_ += 6;

				// Matrix stack.
				// TODO: Factor into a seperate function.
				if( IsIdentity_ == BcFalse )
				{
					MaMat4d Matrix = getMatrix();

					for( BcU32 Idx = 0; Idx < 6; ++Idx )
					{
						ScnCanvasComponentVertex* pVertex = &pFirstVertex[ Idx ];
						MaVec3d Vertex = MaVec3d( pVertex->X_, pVertex->Y_, pVertex->Z_ ) * Matrix;
						pVertex->X_ = Vertex.x();
						pVertex->Y_ = Vertex.y();
						pVertex->Z_ = Vertex.z();
						pVertex->W_ = 1.0f;
					}
				}
				
				AddNewPrimitive = BcFalse;
			}
		}
		
		// Add primitive.
		if( AddNewPrimitive == BcTrue )
		{
			addPrimitive( RsTopologyType::TRIANGLE_LIST, pFirstVertex, 6, Layer, BcTrue );
		}
	}
}
Example #7
0
//////////////////////////////////////////////////////////////////////////
// drawLine
void ScnCanvasComponent::drawLine( const MaVec2d& PointA, const MaVec2d& PointB, const RsColour& Colour, BcU32 Layer )
{
	ScnCanvasComponentVertex* pVertices = allocVertices( 2 );
	ScnCanvasComponentVertex* pFirstVertex = pVertices;
	
	// Only draw if we can allocate vertices.
	if( pVertices != NULL )
	{
		// Now copy in data.
		BcU32 ABGR = Colour.asABGR();
		
		pVertices->X_ = PointA.x();
		pVertices->Y_ = PointA.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->ABGR_ = ABGR;
		++pVertices;
		pVertices->X_ = PointB.x();
		pVertices->Y_ = PointB.y();
		pVertices->Z_ = 0.0f;
		pVertices->W_ = 1.0f;
		pVertices->ABGR_ = ABGR;

		// Quickly check last primitive.
		BcBool AddNewPrimitive = BcTrue;
		if( LastPrimitiveSection_ != BcErrorCode )
		{
			ScnCanvasComponentPrimitiveSection& PrimitiveSection = PrimitiveSectionList_[ LastPrimitiveSection_ ];

			// If the last primitive was the same type as ours we can append to it.
			// NOTE: Need more checks here later.
			if( PrimitiveSection.Type_ == RsTopologyType::LINE_LIST &&
				PrimitiveSection.Layer_ == Layer &&
				PrimitiveSection.MaterialComponent_ == MaterialComponent_ )
			{
				PrimitiveSection.NoofVertices_ += 2;

				// Matrix stack.
				// TODO: Factor into a seperate function.
				if( IsIdentity_ == BcFalse )
				{
					MaMat4d Matrix = getMatrix();

					for( BcU32 Idx = 0; Idx < 2; ++Idx )
					{
						ScnCanvasComponentVertex* pVertex = &pFirstVertex[ Idx ];
						MaVec3d Vertex = MaVec3d( pVertex->X_, pVertex->Y_, pVertex->Z_ ) * Matrix;
						pVertex->X_ = Vertex.x();
						pVertex->Y_ = Vertex.y();
						pVertex->Z_ = Vertex.z();
						pVertices->W_ = 1.0f;
					}
				}
				
				AddNewPrimitive = BcFalse;
			}
		}
		
		// Add primitive.
		if( AddNewPrimitive == BcTrue )
		{
			addPrimitive( RsTopologyType::LINE_LIST, pFirstVertex, 2, Layer, BcTrue );
		}
	}
}
Example #8
0
//////////////////////////////////////////////////////////////////////////
// buildTangents
void MdlMesh::buildTangents()
{
	MaVec3d* pTan1 = new MaVec3d[ aVertices_.size() * 2 ];
	MaVec3d* pTan2 = pTan1 + aVertices_.size();

	memset( pTan1, 0, sizeof( MaVec3d ) * aVertices_.size() * 2 );

	for ( BcU32 i = 0; i < ( aIndices_.size() / 3 ); ++i )
	{
		BcU32 TA = aIndices_[ ( i * 3 ) + 0 ].iVertex_;
		BcU32 TB = aIndices_[ ( i * 3 ) + 1 ].iVertex_;
		BcU32 TC = aIndices_[ ( i * 3 ) + 2 ].iVertex_;

		MdlVertex& VertA = aVertices_[ TA ];
		MdlVertex& VertB = aVertices_[ TB ];
		MdlVertex& VertC = aVertices_[ TC ];

		MaVec3d VertPosA = VertA.Position_;
		MaVec3d VertPosB = VertB.Position_;
		MaVec3d VertPosC = VertC.Position_;

		MaVec2d VertUVA = VertA.UV_;
		MaVec2d VertUVB = VertB.UV_;
		MaVec2d VertUVC = VertC.UV_;

		BcF32 X1 = VertPosB.x() - VertPosA.x();
		BcF32 X2 = VertPosC.x() - VertPosA.x();
		BcF32 Y1 = VertPosB.y() - VertPosA.y();
		BcF32 Y2 = VertPosC.y() - VertPosA.y();
		BcF32 Z1 = VertPosB.z() - VertPosA.z();
		BcF32 Z2 = VertPosC.z() - VertPosA.z();

		BcF32 S1 = VertUVB.x() - VertUVA.x();
		BcF32 S2 = VertUVC.x() - VertUVA.x();
		BcF32 T1 = VertUVB.y() - VertUVA.y();
		BcF32 T2 = VertUVC.y() - VertUVA.y();

		BcF32 InvR = ( S1 * T2 - S2 * T1 );
		BcF32 R = 1.0f / InvR;

		// Validation so it doesn't break everything, just set to a dummy value.
		if( BcAbs( InvR ) < 1e-6f )
		{
			R = 0.0f;
		}

		MaVec3d SDir( ( T2 * X1 - T1 * X2 ) * R, ( T2 * Y1 - T1 * Y2 ) * R, ( T2 * Z1 - T1 * Z2 ) * R );
		MaVec3d TDir( ( S1 * X2 - S2 * X1 ) * R, ( S1 * Y2 - S2 * Y1 ) * R, ( S1 * Z2 - S2 * Z1 ) * R );

		pTan1[ TA ] += SDir;
		pTan1[ TB ] += SDir;
		pTan1[ TC ] += SDir;

		pTan2[ TA ] += TDir;
		pTan2[ TB ] += TDir;
		pTan2[ TC ] += TDir;
	}

	for ( BcU32 i = 0; i < aVertices_.size(); ++i )
	{
		MdlVertex& Vert = aVertices_[ i ];
		MaVec3d Tangent;

		const MaVec3d N = Vert.Normal_;
		const MaVec3d& T = pTan1[ i ];

		Tangent = ( T - N * N.dot( T ) );
		Tangent.normalise();

		// Calculate handedness
		BcF32 W = ( N.cross( T ).dot( pTan2[ i ] ) < 0.0f ) ? -1.0f : 1.0f;

		if ( W < 0.0f )
		{
			Tangent = -Tangent;
		}

		Vert.bTangent_ = BcTrue;
		Vert.Tangent_ = Tangent;

		// Validate, and create a dummy value.
		BcF32 Mag = Tangent.magnitude(); 
		if( BcAbs( Mag - 1.0f ) > 0.0001f )
		{
			Vert.Tangent_.set( 0.0f, 0.0f, 0.0f );
		}
	}

	delete[] pTan1;
}
//virtual
void ScnParticleSystemComponent::render( class ScnViewComponent* pViewComponent, RsFrame* pFrame, RsRenderSort Sort )
{
	// Wait for update fence.
	UpdateFence_.wait();

	// Grab vertex buffer and flip for next frame to use.
	TVertexBuffer& VertexBuffer = VertexBuffers_[ CurrentVertexBuffer_ ];
	CurrentVertexBuffer_ = 1 - CurrentVertexBuffer_;

	// Lock vertex buffer.
	VertexBuffer.pVertexBuffer_->lock();

	// Iterate over alive particles, and setup vertex buffer.
	BcU32 NoofParticlesToRender = 0;
	ScnParticleVertex* pVertex = VertexBuffer.pVertexArray_;
	for( BcU32 Idx = 0; Idx < NoofParticles_; ++Idx )
	{
		ScnParticle& Particle = pParticleBuffer_[ Idx ];

		if( Particle.Alive_ )
		{
			// Half size.
			const MaVec2d HalfSize = Particle.Scale_ * 0.5f;
			const BcF32 MaxHalfSize = BcMax( HalfSize.x(), HalfSize.y() );
			BcAssert( Particle.TextureIndex_ < UVBounds_.size() );
			const MaVec4d& UVBounds( UVBounds_[ Particle.TextureIndex_ ] );

			// Crappy rotation implementation :P
			const BcF32 Radians = Particle.Rotation_;
			MaVec2d CornerA = MaVec2d( -1.0f, -1.0f ) * HalfSize;
			MaVec2d CornerB = MaVec2d(  1.0f, -1.0f ) * HalfSize;
			MaVec2d CornerC = MaVec2d(  1.0f,  1.0f ) * HalfSize;
			MaVec2d CornerD = MaVec2d( -1.0f,  1.0f ) * HalfSize;
			if( Radians != NULL )
			{
				MaMat4d Rotation;
				Rotation.rotation( MaVec3d( 0.0f, 0.0f, Radians ) );
				CornerA = CornerA * Rotation;
				CornerB = CornerB * Rotation;
				CornerC = CornerC * Rotation;
				CornerD = CornerD * Rotation;
			}

			const BcU32 Colour = Particle.Colour_.asABGR();

			// Grab vertices.
			ScnParticleVertex& VertexA = *pVertex++;
			ScnParticleVertex& VertexB = *pVertex++;
			ScnParticleVertex& VertexC = *pVertex++;

			ScnParticleVertex& VertexD = *pVertex++;
			ScnParticleVertex& VertexE = *pVertex++;
			ScnParticleVertex& VertexF = *pVertex++;
			
			// 
			VertexA.X_ = Particle.Position_.x();
			VertexA.Y_ = Particle.Position_.y();
			VertexA.Z_ = Particle.Position_.z();
			VertexA.NX_ = CornerA.x();
			VertexA.NY_ = CornerA.y();
			VertexA.NZ_ = 0.0f;
			VertexA.U_ = UVBounds.x();
			VertexA.V_ = UVBounds.y();
			VertexA.RGBA_ = Colour;

			// 
			VertexB.X_ = Particle.Position_.x();
			VertexB.Y_ = Particle.Position_.y();
			VertexB.Z_ = Particle.Position_.z();
			VertexB.NX_ = CornerB.x();
			VertexB.NY_ = CornerB.y();
			VertexB.NZ_ = 0.0f;
			VertexB.U_ = UVBounds.z();
			VertexB.V_ = UVBounds.y();
			VertexB.RGBA_ = Colour;

			// 
			VertexC.X_ = Particle.Position_.x();
			VertexC.Y_ = Particle.Position_.y();
			VertexC.Z_ = Particle.Position_.z();
			VertexC.NX_ = CornerC.x();
			VertexC.NY_ = CornerC.y();
			VertexC.NZ_ = 0.0f;
			VertexC.U_ = UVBounds.z();
			VertexC.V_ = UVBounds.w();
			VertexC.RGBA_ = Colour;

			// 
			VertexD.X_ = Particle.Position_.x();
			VertexD.Y_ = Particle.Position_.y();
			VertexD.Z_ = Particle.Position_.z();
			VertexD.NX_ = CornerC.x();
			VertexD.NY_ = CornerC.y();
			VertexD.NZ_ = 0.0f;
			VertexD.U_ = UVBounds.z();
			VertexD.V_ = UVBounds.w();
			VertexD.RGBA_ = Colour;

			// 
			VertexE.X_ = Particle.Position_.x();
			VertexE.Y_ = Particle.Position_.y();
			VertexE.Z_ = Particle.Position_.z();
			VertexE.NX_ = CornerD.x();
			VertexE.NY_ = CornerD.y();
			VertexE.NZ_ = 0.0f;
			VertexE.U_ = UVBounds.x();
			VertexE.V_ = UVBounds.w();
			VertexE.RGBA_ = Colour;

			// 
			VertexF.X_ = Particle.Position_.x();
			VertexF.Y_ = Particle.Position_.y();
			VertexF.Z_ = Particle.Position_.z();
			VertexF.NX_ = CornerA.x();
			VertexF.NY_ = CornerA.y();
			VertexF.NZ_ = 0.0f;
			VertexF.U_ = UVBounds.x();
			VertexF.V_ = UVBounds.y();
			VertexF.RGBA_ = Colour;
			
			//
			++NoofParticlesToRender;
		}
	}

	// Update and unlock vertex buffer.	
	VertexBuffer.pVertexBuffer_->setNoofUpdateVertices( NoofParticlesToRender * 6 );
	VertexBuffer.pVertexBuffer_->unlock();

	// Draw particles last.
	if( NoofParticlesToRender > 0 )
	{
		Sort.Layer_ = 15;

		// Bind material.
		if( IsLocalSpace_ )
		{
			const MaMat4d& WorldTransform = getParentEntity()->getWorldMatrix();
			MaterialComponent_->setParameter( WorldTransformParam_, WorldTransform );
		}
		else
		{
			MaterialComponent_->setParameter( WorldTransformParam_, MaMat4d() );
		}

		// Set material parameters for view.
		pViewComponent->setMaterialParameters( MaterialComponent_ );

		// Bind material component.
		MaterialComponent_->bind( pFrame, Sort );

		// Setup render node.
		ScnParticleSystemComponentRenderNode* pRenderNode = pFrame->newObject< ScnParticleSystemComponentRenderNode >();
		pRenderNode->pPrimitive_ = VertexBuffer.pPrimitive_;
		pRenderNode->NoofIndices_ = NoofParticlesToRender * 6;

		// Add to frame.
		pRenderNode->Sort_ = Sort;
		pFrame->addRenderNode( pRenderNode );
	}
}
Example #10
0
//////////////////////////////////////////////////////////////////////////
// update
void GaStructureComponent::update( BcF32 Tick )
{
	// Get water.
	auto Water = getParentEntity()->getComponentAnyParentByType< GaWaterComponent >();

	// If we have point masses, calculate position.
	const size_t NoofPointMasses = Physics_->getNoofPointMasses();
	if( Physics_->getNoofPointMasses() > 0 )
	{
		// Points with weight.
		const BcF32 Gravity = 500.0f;
		for( auto WeightedPoint : WeightedPoints_ )
		{
			Physics_->setPointMassAcceleration( WeightedPoint, MaVec2d( 0.0f, Gravity ) );
		}

		// Points with bouyancy.
		for( auto BouyantPoint : BouyantPoints_ )
		{
			const auto& PointMass = Physics_->getPointMass( BouyantPoint );
			auto WaterPosition = Water->getWaterSurfacePosition( PointMass.CurrPosition_ );
			BcF32 Diff = PointMass.CurrPosition_.y() - WaterPosition.y();

			if( Diff > 1.0f )
			{
				Physics_->setPointMassAcceleration( BouyantPoint, MaVec2d( 0.0f, -Gravity ) );
			}
			else
			{
				Physics_->setPointMassAcceleration( BouyantPoint, MaVec2d( 0.0f, Gravity ) );
			}
		}

		// Position.
		MaVec2d Centre( Physics_->getPointMassPosition( 0 ) );
		getParentEntity()->setLocalPosition( MaVec3d( Centre, 0.0f ) );

		// Rotation.
		MaVec2d Direction = Centre - Physics_->getPointMassPosition( 1 ); 
		BcF32 Angle = std::atan2f( Direction.x(), Direction.y() );
		Sprite_->setRotation( Angle );

		if( Timer_ <= CalculatedFireRate_ )
		{
			Timer_ += Tick;
		}
	}
	
	switch( StructureType_ )
	{
	case GaStructureType::BASE:
		break;
	case GaStructureType::TURRET:
		if( Timer_ >= CalculatedFireRate_ )
		{
			// Find a tentacle.
			GaTentacleComponent* NearestTentacle = Game_->getNearestTentacle( getParentEntity()->getWorldPosition().xy(), BcFalse );
			if( NearestTentacle == nullptr )
			{
				NearestTentacle = Game_->getNearestTentacle( getParentEntity()->getWorldPosition().xy(), BcTrue );
			}
				
			// Spawn a projectile.
			if( NearestTentacle && TemplateProjectile_ )
			{
				auto Entity = ScnCore::pImpl()->spawnEntity( ScnEntitySpawnParams( 
					BcName::INVALID, TemplateProjectile_,
					getParentEntity()->getWorldMatrix(),
					Game_->getParentEntity() ) );
				auto Projectile = Entity->getComponentByType< GaProjectileComponent >();
				Projectile->setLevel( Level_ );
				Projectile->setTarget( NearestTentacle->getParentEntity() );
				Game_->launchProjectile( Projectile );

				// Time to spawn!
				Timer_ -= CalculatedFireRate_;
			}
		}
		break;

	case GaStructureType::RESOURCE:
		break;

	case GaStructureType::POTATO:
		break;

	case GaStructureType::MINE:
		break;
	}
}
//virtual
void ScnParticleSystemComponent::render( class ScnViewComponent* pViewComponent, RsFrame* pFrame, RsRenderSort Sort )
{
	// Wait for update fence.
	UpdateFence_.wait();

	// Grab vertex buffer and flip for next frame to use.
	TVertexBuffer& VertexBuffer = VertexBuffers_[ CurrentVertexBuffer_ ];
	CurrentVertexBuffer_ = 1 - CurrentVertexBuffer_;

	// Calculate lock size.
	BcU32 NoofParticlesToRender = 0;
	for( BcU32 Idx = 0; Idx < NoofParticles_; ++Idx )
	{
		ScnParticle& Particle = pParticleBuffer_[ Idx ];

		if( Particle.Alive_ )
		{
			++NoofParticlesToRender;
		}
	}

	// Lock vertex buffer.
	if( NoofParticlesToRender > 0 )
	{
		UploadFence_.increment();
		RsCore::pImpl()->updateBuffer( 
			VertexBuffer.pVertexBuffer_,
			0,
			NoofParticlesToRender * sizeof( ScnParticleVertex ) * 6,
			RsResourceUpdateFlags::ASYNC,
			[ this, NoofParticlesToRender ]
			( RsBuffer* Buffer, const RsBufferLock& Lock )
			{
				BcU32 NoofParticlesRendered = 0;
				ScnParticleVertex* pVertex = reinterpret_cast< ScnParticleVertex* >( Lock.Buffer_ );
				for( BcU32 Idx = 0; Idx < NoofParticles_; ++Idx )
				{
					ScnParticle& Particle = pParticleBuffer_[ Idx ];

					if( Particle.Alive_ )
					{
						++NoofParticlesRendered;

						// Half size.
						const MaVec2d HalfSize = Particle.Scale_ * 0.5f;
						BcAssert( Particle.TextureIndex_ < UVBounds_.size() );
						const MaVec4d& UVBounds( UVBounds_[ Particle.TextureIndex_ ] );

						// Crappy rotation implementation :P
						const BcF32 Radians = Particle.Rotation_;
						MaVec2d CornerA = MaVec2d( -1.0f, -1.0f ) * HalfSize;
						MaVec2d CornerB = MaVec2d(  1.0f, -1.0f ) * HalfSize;
						MaVec2d CornerC = MaVec2d(  1.0f,  1.0f ) * HalfSize;
						MaVec2d CornerD = MaVec2d( -1.0f,  1.0f ) * HalfSize;
						
						if( Radians != 0.0f )
						{
							MaMat4d Rotation;
							Rotation.rotation( MaVec3d( 0.0f, 0.0f, Radians ) );
							CornerA = CornerA * Rotation;
							CornerB = CornerB * Rotation;
							CornerC = CornerC * Rotation;
							CornerD = CornerD * Rotation;
						}

						const BcU32 Colour = Particle.Colour_.asABGR();

						// Grab vertices.
						ScnParticleVertex& VertexA = *pVertex++;
						ScnParticleVertex& VertexB = *pVertex++;
						ScnParticleVertex& VertexC = *pVertex++;

						ScnParticleVertex& VertexD = *pVertex++;
						ScnParticleVertex& VertexE = *pVertex++;
						ScnParticleVertex& VertexF = *pVertex++;
			
						// 
						VertexA.X_ = Particle.Position_.x();
						VertexA.Y_ = Particle.Position_.y();
						VertexA.Z_ = Particle.Position_.z();
						VertexA.W_ = 1.0f;
						VertexA.NX_ = CornerA.x();
						VertexA.NY_ = CornerA.y();
						VertexA.NZ_ = 0.0f;
						VertexA.U_ = UVBounds.x();
						VertexA.V_ = UVBounds.y();
						VertexA.RGBA_ = Colour;

						// 
						VertexB.X_ = Particle.Position_.x();
						VertexB.Y_ = Particle.Position_.y();
						VertexB.Z_ = Particle.Position_.z();
						VertexB.W_ = 1.0f;
						VertexB.NX_ = CornerB.x();
						VertexB.NY_ = CornerB.y();
						VertexB.NZ_ = 0.0f;
						VertexB.U_ = UVBounds.z();
						VertexB.V_ = UVBounds.y();
						VertexB.RGBA_ = Colour;

						// 
						VertexC.X_ = Particle.Position_.x();
						VertexC.Y_ = Particle.Position_.y();
						VertexC.Z_ = Particle.Position_.z();
						VertexC.W_ = 1.0f;
						VertexC.NX_ = CornerC.x();
						VertexC.NY_ = CornerC.y();
						VertexC.NZ_ = 0.0f;
						VertexC.U_ = UVBounds.z();
						VertexC.V_ = UVBounds.w();
						VertexC.RGBA_ = Colour;

						// 
						VertexD.X_ = Particle.Position_.x();
						VertexD.Y_ = Particle.Position_.y();
						VertexD.Z_ = Particle.Position_.z();
						VertexD.W_ = 1.0f;
						VertexD.NX_ = CornerC.x();
						VertexD.NY_ = CornerC.y();
						VertexD.NZ_ = 0.0f;
						VertexD.U_ = UVBounds.z();
						VertexD.V_ = UVBounds.w();
						VertexD.RGBA_ = Colour;

						// 
						VertexE.X_ = Particle.Position_.x();
						VertexE.Y_ = Particle.Position_.y();
						VertexE.Z_ = Particle.Position_.z();
						VertexE.W_ = 1.0f;
						VertexE.NX_ = CornerD.x();
						VertexE.NY_ = CornerD.y();
						VertexE.NZ_ = 0.0f;
						VertexE.U_ = UVBounds.x();
						VertexE.V_ = UVBounds.w();
						VertexE.RGBA_ = Colour;

						// 
						VertexF.X_ = Particle.Position_.x();
						VertexF.Y_ = Particle.Position_.y();
						VertexF.Z_ = Particle.Position_.z();
						VertexF.W_ = 1.0f;
						VertexF.NX_ = CornerA.x();
						VertexF.NY_ = CornerA.y();
						VertexF.NZ_ = 0.0f;
						VertexF.U_ = UVBounds.x();
						VertexF.V_ = UVBounds.y();
						VertexF.RGBA_ = Colour;
					}
				}

				BcAssert( NoofParticlesRendered == NoofParticlesToRender );
				UploadFence_.decrement();
			} );
	}

	// Update uniform buffer.
	if( IsLocalSpace_ )
	{
		VertexBuffer.ObjectUniforms_.WorldTransform_ = getParentEntity()->getWorldMatrix();
	}
	else
	{
		VertexBuffer.ObjectUniforms_.WorldTransform_ = MaMat4d();
	}

	// Upload uniforms.
	RsCore::pImpl()->updateBuffer( 
		VertexBuffer.UniformBuffer_,
		0, sizeof( VertexBuffer.ObjectUniforms_ ),
		RsResourceUpdateFlags::ASYNC,
		[ this, VertexBuffer ]( RsBuffer* Buffer, const RsBufferLock& Lock )
		{
			BcMemCopy( Lock.Buffer_, &VertexBuffer.ObjectUniforms_, sizeof( VertexBuffer.ObjectUniforms_ ) );
		} );

	// Draw particles last.
	if( NoofParticlesToRender > 0 )
	{
		Sort.Layer_ = 15;

		// Set material parameters for view.
		pViewComponent->setMaterialParameters( MaterialComponent_ );

		// Bind material component.
		MaterialComponent_->bind( pFrame, Sort );

		// Setup render node.
		ScnParticleSystemComponentRenderNode* pRenderNode = pFrame->newObject< ScnParticleSystemComponentRenderNode >();
		pRenderNode->VertexBuffer_ = VertexBuffer.pVertexBuffer_;
		pRenderNode->VertexDeclaration_ = VertexDeclaration_;
		pRenderNode->NoofIndices_ = NoofParticlesToRender * 6;

		// Add to frame.
		pRenderNode->Sort_ = Sort;
		pFrame->addRenderNode( pRenderNode );
	}
}
Example #12
0
//////////////////////////////////////////////////////////////////////////
// drawSpriteCentered
void ScnCanvasComponent::drawSpriteCenteredUp3D( const MaVec3d& Position, const MaVec2d& Size, BcU32 TextureIdx, const RsColour& Colour, BcU32 Layer )
{
	MaVec3d NewPosition = Position - MaVec3d( Size.x() * 0.5f, 0.0f, Size.y() * 0.5f );
	drawSpriteUp3D( NewPosition, Size, TextureIdx, Colour, Layer );
}