////////////////////////////////////////////////////////////////////////// // PsyLaunchGame void PsyLaunchGame() { ScnEntitySpawnParams ScreenEntityParams = { "default", "ScreenEntity", "ScreenEntity_0", MaMat4d(), nullptr, }; ScreenEntityParams.OnSpawn_ = []( ScnEntity* ParentEntity ) { ScnEntitySpawnParams CameraEntityParams = { "default", "CameraEntity", "CameraEntity_0", MaMat4d(), ParentEntity, nullptr }; ScnCore::pImpl()->spawnEntity( CameraEntityParams ); ScnEntitySpawnParams StartGameEntityParams = { "default", "CustomisationEntity", "CustomisationEntity_0", MaMat4d(), ParentEntity, nullptr }; ScnCore::pImpl()->spawnEntity( StartGameEntityParams ); }; ScnCore::pImpl()->spawnEntity( ScreenEntityParams ); }
////////////////////////////////////////////////////////////////////////// // onAttach //virtual void GaRobotComponent::onAttach( ScnEntityWeakRef Parent ) { Super::onAttach( Parent ); StartPosition_ = Parent->getLocalPosition(); TargetPosition_ = Parent->getLocalPosition(); Canvas_ = Parent->getComponentAnyParentByType< ScnCanvasComponent >(); Material_ = Parent->getComponentAnyParent( "DefaultCanvasMaterial_0" ); View_ = ScnCore::pImpl()->findEntity( "CameraEntity_0" )->getComponentByType< ScnViewComponent >(); auto spawnPart = [ & ]( const BcName PartName ) { ScnEntitySpawnParams EntityParams = { "default", PartName, BcName( PartName.getValue(), getParentEntity()->getName().getID() ), MaMat4d(), getParentEntity() }; return ScnCore::pImpl()->spawnEntity( EntityParams ); }; Base_ = spawnPart( "RobotBase" ); Turret_ = spawnPart( "RobotTurret" ); MoveAngle_ = getName().getID() == 0 ? 0.0f : BcPI; }
////////////////////////////////////////////////////////////////////////// // render void ScnCanvasComponent::clear() { // Set current render resource. pRenderResource_ = &RenderResources_[ CurrentRenderResource_ ]; // Set vertices up. pVertices_ = pVerticesEnd_ = pRenderResource_->pVertices_; pVerticesEnd_ += NoofVertices_; VertexIndex_ = 0; // Empty primitive sections. PrimitiveSectionList_.clear(); // Reset matrix stack. MatrixStack_.clear(); MatrixStack_.push_back( MaMat4d() ); IsIdentity_ = BcTrue; // Lock vertex buffer for use. if( HaveVertexBufferLock_ == BcFalse ) { pRenderResource_->pVertexBuffer_->lock(); HaveVertexBufferLock_ = BcTrue; } // Clear last primitive. LastPrimitiveSection_ = BcErrorCode; }
////////////////////////////////////////////////////////////////////////// // recursiveParseAnimatedNodes void ScnAnimationImport::recursiveParseAnimatedNodes( struct aiNode* Node, size_t ParentNodeIdx ) { #if PSY_IMPORT_PIPELINE AnimatedNode AnimatedNode; aiMatrix4x4 WorldTransform = Node->mParent != nullptr ? Node->mParent->mTransformation * Node->mTransformation : Node->mTransformation; AnimatedNode.Name_ = Node->mName.C_Str(); AnimatedNode.LocalTransform_ = MaMat4d( Node->mTransformation[ 0 ] ).transposed(); AnimatedNode.WorldTransform_ = MaMat4d( WorldTransform[ 0 ] ).transposed(); AnimatedNode.ParentIdx_ = static_cast< BcU32 >( ParentNodeIdx ); AnimatedNodes_.push_back( AnimatedNode ); for( BcU32 ChildIdx = 0; ChildIdx < Node->mNumChildren; ++ChildIdx ) { recursiveParseAnimatedNodes( Node->mChildren[ ChildIdx ], AnimatedNodes_.size() - 1 ); } #endif }
////////////////////////////////////////////////////////////////////////// // initialise //virtual void ScnCanvasComponent::initialise( BcU32 NoofVertices ) { Super::initialise(); // NULL internals. BcMemZero( &RenderResources_[ 0 ], sizeof( RenderResources_ ) ); HaveVertexBufferLock_ = BcFalse; // Setup matrix stack with an identity matrix and reserve. MatrixStack_.reserve( 16 ); MatrixStack_.push_back( MaMat4d() ); IsIdentity_ = BcTrue; // Store number of vertices. NoofVertices_ = NoofVertices; // Which render resource to use. CurrentRenderResource_ = 0; }
////////////////////////////////////////////////////////////////////////// // render void ScnCanvasComponent::clear() { // Wait for vertex buffer to finish uploading. UploadFence_.wait(); // Set vertices up. pVertices_ = pVerticesEnd_ = pWorkingVertices_; pVerticesEnd_ += NoofVertices_; VertexIndex_ = 0; // Empty primitive sections. PrimitiveSectionList_.clear(); // Reset matrix stack. MatrixStack_.clear(); MatrixStack_.push_back( MaMat4d() ); IsIdentity_ = BcTrue; // Clear last primitive. LastPrimitiveSection_ = BcErrorCode; }
//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 ); } }
//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 ); } }
////////////////////////////////////////////////////////////////////////// // onAttach //virtual void GaIntroComponent::onAttach( ScnEntityWeakRef Parent ) { OsCore::pImpl()->subscribe( osEVT_INPUT_KEYDOWN, this, [ this ]( EvtID ID, const EvtBaseEvent& BaseEvent ) { if( Timer_ > 5.0f ) { ScnCore::pImpl()->spawnEntity( ScnEntitySpawnParams( "SceneEntity", "default", "SceneEntity", MaMat4d(), getParentEntity()->getParentEntity() ) ); ScnCore::pImpl()->removeEntity( getParentEntity() ); return evtRET_REMOVE; } return evtRET_PASS; } ); Canvas_ = getComponentAnyParentByType< ScnCanvasComponent >(); BcAssert( Canvas_ ); Font_ = getComponentAnyParentByType< ScnFontComponent >(); BcAssert( Font_ ); Super::onAttach( Parent ); }