欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ArcGIS Maps SDK for Unreal Engine demo

程序员文章站 2022-06-10 23:27:43
...

ArcGIS Maps SDK for Unreal Engine demo

插件主要分为两部分:ArcGIS数据API接口和UE4渲染部分。

UArcGISRendererComponent继承自AActor,包含以下对象:
ArcGISRendererView 负责组织数据源map,更新位置camera,坐标转换coords。
SceneComponentProvider :有地图数据动态生成Mesh组件,并挂载到UArcGISRendererComponent下。
GPUResourcesProvider : 材质资源的生成。
NormalMapGenerator :法向量。
TextureComposer :纹理混合。
Matrix :CoordinateSystem
FArcGISRenderer: 实际渲染的实现。

void UArcGISRendererComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	if (RendererView)
	{
		//准备相关渲染处理函数
		if (!ArcGISRenderer)
		{
			//GPU资源相关处理
			GPUResourcesProvider = std::make_shared<FGPUResourcesProvider>();
			
			//Mesh资源相关处理
			SceneComponentProvider = std::make_shared<FSceneComponentProvider>(this);
			//纹理资源相关处理
			TextureComposer = std::make_shared<FTextureComposer>(this, GPUResourcesProvider);
			//法线向量相关处理
			NormalMapGenerator = std::make_shared<FNormalMapGenerator>(this, GPUResourcesProvider);
			//生成渲染对象
			ArcGISRenderer =
				Esri::MakeShared<Esri::ArcGISMapsSDKLib::FArcGISRenderer>(RendererView, GPUResourcesProvider->GetFunctions(), SceneComponentProvider->GetFunctions(),
												  TextureComposer->GetFunctions(), NormalMapGenerator->GetFunctions());

			CoordinateSystem = RendererView->GetCoordinateSystem();
			RepositionAllActors(CoordinateSystem);
		}
		//每一帧渲染,开始渲染
		ArcGISRenderer->Tick(DeltaTime);

		UpdateCoordinateSystem();
	}
}

示例

  • Create the map document
  • Add a basemap
  • Set the basemap
  • Set the elevation
  • Create other layers
  • Create extent
  • Create a camera
  • Create the renderer view and set it the camera and the map
  • Set the renderer view to the renderer component
  • Create our sample pawn
  • Assign renderview to the current main camera component
  • Add reposition components to the directional and sky lights
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"

#include "Components/ArcGISRendererComponent.h"

#include "SampleAPIMapCreator.generated.h"

// The declaration of our Actor class
UCLASS()
class ARCGISSAMPLES_API ASampleAPIMapCreator : public AActor
{
	GENERATED_BODY()

public:
	ASampleAPIMapCreator();

protected:
	virtual void BeginPlay() override;

private:
	UArcGISRendererComponent* ArcGISRendererComponent;

	void CreateArcGISMap();
};
#include "SampleAPIMapCreator.h"

#include "Components/DirectionalLightComponent.h"
#include "Components/SkyLightComponent.h"
#include "Engine/DirectionalLight.h"
#include "Engine/SkyLight.h"
#include "Engine/World.h"
#include "Kismet/GameplayStatics.h"

#include "ArcGISMapsSDKLib/API/GameEngine/Camera/ArcGISCamera.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGIS3DModelLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGISBasemapLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGISElevationLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Layers/ArcGISImageLayer.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/ArcGISMap.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/ArcGISMapElevation.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/ArcGISMapType.h"
#include "ArcGISMapsSDKLib/API/GameEngine/Map/Extent/ArcGISMapExtentRectangle.h"
#include "ArcGISMapsSDKLib/API/Unreal/Collection.h"

#include "Components/ArcGISDirectionalLightRepositionComponent.h"
#include "Components/ArcGISSkyLightRepositionComponent.h"

#include "Math/Convert.h"
#include "SampleDefaultPawn.h"

ASampleAPIMapCreator::ASampleAPIMapCreator()
{
	PrimaryActorTick.bCanEverTick = false;
	//生成渲染组件
	ArcGISRendererComponent = CreateDefaultSubobject<UArcGISRendererComponent>(TEXT("ArcGISRendererComponent"));
	AddOwnedComponent(ArcGISRendererComponent);
}

void ASampleAPIMapCreator::BeginPlay()
{
	Super::BeginPlay();
	CreateArcGISMap();
}

// We create our map with this method
void ASampleAPIMapCreator::CreateArcGISMap()
{
	// API Key
	constexpr auto apiKey = ""; // 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b";

	// Create the map document
	auto mapType = Esri::GameEngine::Map::ArcGISMapType::Global;
	auto arcGISMap = Esri::MakeShared<Esri::GameEngine::Map::ArcGISMap>(mapType);

	// Add a basemap
	auto arcGISBasemapLayer = Esri::GameEngine::Layers::ArcGISBasemapLayer(
		"https://www.arcgis.com/sharing/rest/content/items/716b600dbbac433faa4bec9220c76b3a/data", apiKey);

	// Set the basemap
	arcGISMap->SetBasemapLayer(arcGISBasemapLayer);

	// Set the elevation
	auto elevationLayer = Esri::GameEngine::Layers::ArcGISElevationLayer(
		"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer", "Elevation", apiKey);
	arcGISMap->SetElevation(elevationLayer);

	// Create layers
	auto layer_1 = Esri::GameEngine::Layers::ArcGISImageLayer(
		"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/UrbanObservatory_NYC_TransitFrequency/MapServer", "MyLayer_1", 1.0f,
		true, apiKey);
	arcGISMap->GetLayers().Add(layer_1);

	auto layer_2 = Esri::GameEngine::Layers::ArcGISImageLayer(
		"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Industrial/MapServer", "MyLayer_2", 1.0f, true, apiKey);
	arcGISMap->GetLayers().Add(layer_2);

	auto layer_3 = Esri::GameEngine::Layers::ArcGISImageLayer(
		"https://tiles.arcgis.com/tiles/4yjifSiIG17X0gW4/arcgis/rest/services/NewYorkCity_PopDensity/MapServer", "MyLayer_3", 1.0f, true, apiKey);
	arcGISMap->GetLayers().Add(layer_3);

	auto layer_4 = Esri::GameEngine::Layers::ArcGIS3DModelLayer(
		"https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Buildings_NewYork_17/SceneServer", "MyLayer_4", 1.0f, true, apiKey);
	arcGISMap->GetLayers().Add(layer_4);

	// Remove a layer
	auto index = arcGISMap->GetLayers().IndexOf(layer_3);
	arcGISMap->GetLayers().Remove(index);

	// Update properties
	layer_1.SetOpacity(0.9f);
	layer_2.SetOpacity(0.6f);
	layer_4.SetOpacity(1.0f);

	// Create extent
	if (mapType == Esri::GameEngine::Map::ArcGISMapType::Local)
	{
		auto extentCenter = Esri::GameEngine::Location::ArcGISGlobalCoordinatesPosition(40.691242, -74.054921, 3000);
		auto extent = Esri::GameEngine::Map::Extent::ArcGISMapExtentRectangle(extentCenter, 10000, 10000);
		arcGISMap->SetExtent(extent);
	}

	String name("Camera_1");
	Esri::GameEngine::Location::ArcGISRotation orientation(68, 0, 65);
	Esri::GameEngine::Location::ArcGISGlobalCoordinatesPosition position(40.691242, -74.054921, 3000);

	// Create a camera
	auto arcGISCamera = Esri::MakeShared<Esri::GameEngine::Camera::ArcGISCamera>(name, position, orientation);

	// Create the renderer view and set it the camera and the map
	auto rendererView = Esri::MakeShared<Esri::GameEngine::View::ArcGISRendererView>();

	rendererView->SetMap(arcGISMap);
	rendererView->SetCamera(arcGISCamera);

	// Set the renderer view to the renderer component
	ArcGISRendererComponent->RendererView = rendererView;

	// Create our sample pawn
	ASampleDefaultPawn* arcGISPawn = GetWorld()->SpawnActor<ASampleDefaultPawn>();

	// ASSIGN RENDERERVIEW TO THE CURRENT MAIN CAMERA COMPONENT
	auto cameraComponent = arcGISPawn->FindComponentByClass<UArcGISCameraComponent>();
	cameraComponent->RendererView = rendererView;

	arcGISPawn->SetActorLocationAndRotation(Convert::ToFVector(rendererView->GetCameraLocalPosition()),
											Convert::ToFQuat(rendererView->GetCameraLocalRotation()));

	// Add reposition components to the directional and sky lights
	auto directionalLightActor = UGameplayStatics::GetActorOfClass(GetWorld(), ADirectionalLight::StaticClass());
	auto skyLightActor = UGameplayStatics::GetActorOfClass(GetWorld(), ASkyLight::StaticClass());

	if (directionalLightActor)
	{
		auto directionalLightReposition = NewObject<UArcGISDirectionalLightRepositionComponent>(
			directionalLightActor, UArcGISDirectionalLightRepositionComponent::StaticClass(), NAME_None, RF_Transient);
		directionalLightReposition->RendererView = rendererView;
		directionalLightReposition->RegisterComponent();
	}

	if (skyLightActor)
	{
		auto lightReposition =
			NewObject<UArcGISSkyLightRepositionComponent>(skyLightActor, UArcGISSkyLightRepositionComponent::StaticClass(), NAME_None, RF_Transient);
		lightReposition->RendererView = rendererView;
		lightReposition->RegisterComponent();
	}
}
相关标签: UE4 UE4 ArcGIS