// Save/Load to XML
void
ArTrackOrientation::_writeXML(ArRef<XmlNode> node) const
{
node->setName("TrackOrientation");

node->setPropertyReal("duration",_track->getDuration());
node->setPropertyInteger("degree",_track->getDegree());
node->setPropertyInteger("dimension",4);

ArTrackOrientationInterpolator *track=(ArTrackOrientationInterpolator *)_track;
StlVector<unsigned> keysPositions;
track->getKeysPositions(keysPositions);
VectorN<double,4> key;

for (unsigned i=0;i<keysPositions.size();i++)
  {
  track->getKeyFrame(keysPositions[i],key );
  
  ArRef<XmlNode> keyFrame=node->addChild("KeyFrameOrientation");
  keyFrame->setPropertyInteger("frame",keysPositions[i]);
  
  Quaterniond q(key[0],key[1],key[2],key[3]);
  Vector3d axis;
  double angle;
  q.getAxisAngle(axis,angle);
  keyFrame->setPropertyReal("vx",axis.x());
  keyFrame->setPropertyReal("vy",axis.y());
  keyFrame->setPropertyReal("vz",axis.z());
  keyFrame->setPropertyReal("angle",angle);
  
  }
}
Пример #2
0
	void RenderingContext::DrawInParallel( StlVector<std::shared_ptr<RenderingContext>>& contexts, const StlVector<std::shared_ptr<IMesh>>& meshes, int meshCount, FuncPreRender funcPreRender )
	{
		if ( meshes.empty() )
		{
			return;
		}

		if ( contexts.empty() )
		{
			LOG_WARNING( "no contexts" );
			return;
		}

		// Validate the specified rendering contexts.
		for ( auto context : contexts )
		{
			if ( context == nullptr )
			{
				LOG_WARNING( "forbidden null context usage" );
				return;
			}
		}

		if ( meshes.size() < static_cast<size_t>( meshCount ) )
		{
			LOG_WARNING( "invalid mesh count" );
			return;
		}

		// If the number of meshes is less than 4, 
		// draw all meshes on the first context without parallel processing.
		if ( meshCount < Thread::HardwareConcurrency() )
		{
			auto context = contexts[0];
			for ( const auto& mesh : meshes )
			{
				context->Draw( mesh );
			}
			return;
		}


		RenderingDevice* pDevice = RenderingDevice::GetInstance();
		Assert( pDevice );

		size_t numContexts = contexts.size();

		// Note that the world matrix would be multiplied just before drawing a mesh
		// because the world matrix of a mesh is different each other.
		// So premultiply view-projection matrices only.
		Matrix4 viewProj = pDevice->GetViewMatrix() * pDevice->GetProjectionMatrix();

		// Thread objects.
		ThreadPool* threadPool = ThreadPool::GetInstance();
		Atomic<int> workIndex( 0 );

		for ( size_t c = 0; c < numContexts; ++c )
		{
			auto context = contexts[c];
			Assert( context );

			auto task = std::bind(
				[=, &workIndex]( std::shared_ptr<RenderingContext> context, Matrix4 viewProj, FuncPreRender funcPreRender )
				{
					SCOPE_PROFILE_BEGIN( "RenderTask" );

					ConstantBuffer& cbuffer = context->GetSharedConstantBuffer();

					// Until the last index...
					while ( workIndex.Value() < meshCount )
					{
						// Prefech the workIndex to avoid changing the value on other thread, and then increment the workIndex.
						int index = workIndex.FetchAndIncrement();

						// Check the index again to guarantee atomic.
						// FIXME: Is this necessary?
						if ( index >= meshCount )
						{
							return;
						}

						// Call the PreRender functor.
						funcPreRender( context, index );

						// Now compute the final WVP matrix of this mesh.
						Matrix4 wvp = cbuffer.GetMatrix4( ConstantBuffer::WorldMatrix ) * viewProj;
						cbuffer.SetMatrix4( ConstantBuffer::WVPMatrix, wvp );

						// Draw the mesh.
						context->Draw( meshes[index] );
					}

					SCOPE_PROFILE_END();
				},
				context,
				viewProj,
				funcPreRender );

			threadPool->Queue( task );
		}


		// Join all rendering threads.
		SCOPE_PROFILE_BEGIN( "JoinRendering" );
		threadPool->WaitForAllTasks();
		SCOPE_PROFILE_END();

			
		//// Resolve the UAV to display using the main context.
		//// We assume that rendering order is independent.
		//SCOPE_PROFILE_BEGIN( "ResolveUnorderedAccessView " );
		//contexts[0]->ResolveUnorderedAccessViews( contexts );
		//SCOPE_PROFILE_END();
	}
Пример #3
0
KIHX_API void kiRenderToBuffer( void* buffer, int width, int height, int bpp )
{
	if ( buffer == nullptr )
	{
		return;
	}
	
	__UNDONE( temporal testing code );

	// Create color and depth stencil buffers.
	ColorFormat colorFormat = kih::GetSuitableColorFormatFromBpp( bpp );
	static std::shared_ptr<Texture> renderTarget = Texture::Create( width, height, colorFormat, buffer );
	static std::shared_ptr<Texture> depthStencil = Texture::Create( width, height, ColorFormat::D32F, NULL );
	static std::shared_ptr<UnorderedAccessView<OutputMergerInputStream>> omUAV = std::make_shared<UnorderedAccessView<OutputMergerInputStream>>( width * height * 2 );

	// Create rendering contexts as many of Thread::HardwareConcurrency.
	const int Concurrency = 8;	// HACK
	static std::array<std::shared_ptr<RenderingContext>, Concurrency> contexts;
	if ( contexts[0] == nullptr )
	{
		int index = 0;
		LoopUnroll<Concurrency>::Work( 
			[&index]() 
			{ 
				auto context = RenderingDevice::GetInstance()->CreateRenderingContext();
				context->SetViewport( 0, 0, static_cast<unsigned short>( renderTarget->Width() ), static_cast<unsigned short>( renderTarget->Height() ) );
				context->SetFixedPipelineMode( false );
				
				context->SetRenderTarget( renderTarget, 0 );
				context->SetDepthStencil( depthStencil );

				contexts[index++] = context;
			} 
		);
	}
	
	auto context = contexts[0];

	context->Clear( 0, 0, 0, 255 );
	context->SetUnorderedAccessView( nullptr );

	// Draw the world.
	const Matrix4& matWorld = RenderingDevice::GetInstance()->GetWorldMatrix();

	// Grid arragement
	if ( grid_scene.Bool() )
	{
		// threading or not
		if ( concurrency.Int() <= 1 )
		{
			DrawGridScene( context, matWorld );
		}
		else
		{
			// Copy array contexts to vector one.
			StlVector<std::shared_ptr<RenderingContext>> concurrencyContexts;
			concurrencyContexts.resize( concurrency.Int() - 1 );		// the other thread is for resolve.	
			for ( size_t i = 0; i < concurrencyContexts.size(); ++i )
			{
				contexts[i]->SetUnorderedAccessView( omUAV );
				concurrencyContexts[i] = contexts[i];
			}

			DrawGridSceneInParallel( concurrencyContexts, matWorld );
		}
	}
	else
	{
		context->GetSharedConstantBuffer().SetMatrix4( ConstantBuffer::WorldMatrix, matWorld );
		context->GetSharedConstantBuffer().SetVector4( ConstantBuffer::DiffuseColor, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
		context->Draw( GetMeshes()[0] );
	}
}