/** * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. */ class LandscapeComponent extends PrimitiveComponent native(Terrain) hidecategories(Display, Attachment, Physics, Debug, Lighting, Collision, Movement, Rendering, PrimitiveComponent, Object); var() const editconst int SectionBaseX, SectionBaseY; var const int ComponentSizeQuads, // Total number of quads for this component SubsectionSizeQuads, // Number of quads for a subsection of the component. SubsectionSizeQuads+1 must be a power of two. NumSubsections; // Number of subsections in X or Y axis var() MaterialInterface OverrideMaterial; var MaterialInstanceConstant MaterialInstance; /** Stores information about which weightmap texture and channel each layer is stored */ struct native WeightmapLayerAllocationInfo { var Name LayerName; var byte WeightmapTextureIndex; var byte WeightmapTextureChannel; structcpptext { FWeightmapLayerAllocationInfo(FName InLayerName) : LayerName(InLayerName) , WeightmapTextureIndex(255) // Indicates an invalid allocation , WeightmapTextureChannel(255) {} } }; /** List of layers, and the weightmap and channel they are stored */ var private const array WeightmapLayerAllocations; /** Weightmap texture reference */ var private const array WeightmapTextures; /** UV offset to component's weightmap data from component local coordinates*/ var Vector4 WeightmapScaleBias; /** U or V offset into the weightmap for the first subsection, in texture UV space */ var float WeightmapSubsectionOffset; /** UV offset to Heightmap data from component local coordinates */ var Vector4 HeightmapScaleBias; /** Heightmap texture reference */ var private const Texture2D HeightmapTexture; /** Cached bounds, created at heightmap update time */ var const BoxSphereBounds CachedBoxSphereBounds; /** Cached local-space bounding box, created at heightmap update time */ var const Box CachedLocalBox; /** Unique ID for this component, used for caching during distributed lighting */ var private const editoronly Guid LightingGuid; /** Array of shadow maps for this component. */ var private const array ShadowMaps; /** INTERNAL: Array of lights that don't apply to the terrain component. */ var const array IrrelevantLights; /** Reference to the texture lightmap resource. */ var native private const LightMapRef LightMap; `if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) var(PersistentSplats) private const editconst int SplatterMapRes; var private const TWSplatterMap2D SplatterMap; `endif /** Pointer to data shared with the render therad, used by the editor tools */ var private native pointer EditToolRenderData{struct FLandscapeEditToolRenderData}; /** Heightfield mipmap used to generate collision */ var int CollisionMipLevel; /** Platform-specific data */ var private native pointer PlatformData{void}; /** Platform-specific data size */ var const native int PlatformDataSize; var editoronly transient bool bNeedPostUndo; /** Forced LOD level to use when rendering */ var(LOD) int ForcedLOD; /** Neighbor LOD data to use when rendering, 255 is unspecified */ var byte NeighborLOD[8]; /** LOD level Bias to use when rendering */ var(LOD) int LODBias; /** Neighbor LOD bias to use when rendering, 128 is 0 bias, 0 is -128 bias, 255 is 127 bias */ var byte NeighborLODBias[8]; cpptext { // UObject interface virtual void AddReferencedObjects( TArray& ObjectArray ); virtual void Serialize(FArchive& Ar); virtual void BeginDestroy(); #if WITH_EDITOR virtual void PostLoad(); virtual void PostEditImport(); virtual void PostEditUndo(); virtual void PostRename(); // Register ourselves with the actor. ELandscapeSetupErrors SetupActor(UBOOL bForce = FALSE); virtual void Attach(); #endif // UPrimitiveComponent interface virtual FPrimitiveSceneProxy* CreateSceneProxy(); virtual void GetUsedMaterials( TArray& OutMaterials ) const; virtual void UpdateBounds(); void SetParentToWorld(const FMatrix& ParentToWorld); virtual INT GetNumElements() const { return 1; } virtual UMaterialInterface* GetElementMaterial(INT MaterialIndex) const { return MaterialInstance; } virtual void SetElementMaterial(INT ElementIndex, UMaterialInterface* InMaterial); #if WITH_EDITOR class ULandscapeInfo* GetLandscapeInfo(UBOOL bSpawnNewActor = TRUE) const; virtual void GetStaticLightingInfo(FStaticLightingPrimitiveInfo& OutPrimitiveInfo,const TArray& InRelevantLights,const FLightingBuildOptions& Options); virtual UBOOL GetLightMapResolution( INT& Width, INT& Height ) const; virtual void GetStaticTriangles(FPrimitiveTriangleDefinitionInterface* PTDI) const; void DeleteLayer(FName LayerName, struct FLandscapeEditDataInterface* LandscapeEdit); void GeneratePlatformData( UE3::EPlatformType Platform, void*& NewPlatformData, INT& NewPlatformDataSize, UTexture2D*& NewWeightTexture ) const; // Persistent splatter editor support #if __TW_PERSISTENT_SPLATTER_SYSTEM_ virtual void InvalidateSplatterMapData(); virtual void MarkSplatterMapRequiringRebuild(); virtual UBOOL GetPersistentSplatterInfo(FTWPersistentSplatterPrimitiveInfo& OutPrimitiveInfo); virtual UBOOL GetSplatterMapResolution( INT& Width, INT& Height ) const; virtual UBOOL ShouldAllowPersistentSplats() const; virtual void UpdateDependencies(); #endif #endif #if __TW_PERSISTENT_SPLATTER_SYSTEM_ // Persistent splatter support virtual UTWSplatterMap2D* GetSplattermap(const INT LODIndex = 0); #endif virtual void InvalidateLightingCache(); /** * Requests whether the component will use texture, vertex or no lightmaps. * * @return ELightMapInteractionType The type of lightmap interaction the component will use. */ virtual ELightMapInteractionType GetStaticLightingType() const { return LMIT_Texture; } virtual void GetStreamingTextureInfo(TArray& OutStreamingTextures) const; // Decal void GenerateDecalRenderData(FDecalState* Decal, TArray< FDecalRenderData* >& OutDecalRenderDatas) const; // ULandscapeComponent Interface /** Return's the landscape actor associated with this component. */ class ALandscape* GetLandscapeActor() const; class ALandscapeProxy* GetLandscapeProxy() const; TMap< UTexture2D*,struct FLandscapeWeightmapUsage >& GetWeightmapUsageMap(); virtual const FGuid& GetLightingGuid() const { #if WITH_EDITORONLY_DATA return LightingGuid; #else static const FGuid NullGuid( 0, 0, 0, 0 ); return NullGuid; #endif // WITH_EDITORONLY_DATA } virtual void SetLightingGuid() { #if WITH_EDITORONLY_DATA LightingGuid = appCreateGuid(); #endif // WITH_EDITORONLY_DATA } #if WITH_EDITOR // UObject interface virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); /** Initialize the landscape component */ void Init(INT InBaseX,INT InBaseY,INT InComponentSizeQuads, INT InNumSubsections,INT InSubsectionSizeQuads); /** * Recalculate cached bounds using height values. */ void UpdateCachedBounds(); /** * Update the MaterialInstance parameters to match the layer and weightmaps for this component * Creates the MaterialInstance if it doesn't exist. */ void UpdateMaterialInstances(); /** * Generate mipmaps for height and tangent data. * @param HeightmapTextureMipData - array of pointers to the locked mip data. * This should only include the mips that are generated directly from this component's data * ie where each subsection has at least 2 vertices. */ void GenerateHeightmapMips(TArray& HeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT,struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); /** * Generates empty mipmaps for weightmap */ static void CreateEmptyTextureMips(UTexture2D* Texture, UBOOL bClear = FALSE); /** * Generate mipmaps for weightmap * Assumes all weightmaps are unique to this component. * @param WeightmapTextureBaseMipData: array of pointers to each of the weightmaps' base locked mip data. */ template static void GenerateMipsTempl(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, DataType* BaseMipData); static void GenerateWeightmapMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, FColor* BaseMipData); static void GenerateDataMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, BYTE* BaseMipData); /** * Update mipmaps for existing weightmap texture */ template static void UpdateMipsTempl(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, TArray& WeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); static void UpdateWeightmapMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, TArray& WeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); static void UpdateDataMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* Texture, TArray& TextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); /** * Creates or updates collision component height data * @param HeightmapTextureMipData: heightmap data * @param ComponentX1, ComponentY1, ComponentX2, ComponentY2: region to update * @param Whether to update bounds from render component. */ void UpdateCollisionHeightData(FColor* HeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, UBOOL bUpdateBounds=FALSE, UBOOL bRebuild=FALSE); /** * Updates collision component dominant layer data * @param WeightmapTextureMipData: weightmap data * @param ComponentX1, ComponentY1, ComponentX2, ComponentY2: region to update * @param Whether to update bounds from render component. */ void UpdateCollisionLayerData(TArray& WeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT); /** * Updates collision component dominant layer data for the whole component, locking and unlocking the weightmap textures. */ void UpdateCollisionLayerData(); /** * Creates weightmaps for this component for the layers specified in the WeightmapLayerAllocations array */ void ReallocateWeightmaps(struct FLandscapeEditDataInterface* DataInterface=NULL); /** * Generate a key for this component's layer allocations to use with MaterialInstanceConstantMap. */ UMaterialInterface* GetLandscapeMaterial() const; FString GetLayerAllocationKey() const; void GetLayerDebugColorKey(INT& R, INT& G, INT& B) const; void RemoveInvalidWeightmaps(); virtual void ExportCustomProperties(FOutputDevice& Out, UINT Indent); virtual void ImportCustomProperties(const TCHAR* SourceText, FFeedbackContext* Warn); void InitHeightmapData(TArray& Heights, UBOOL bUpdateCollision); void InitWeightmapData(TArray& LayerNames, TArray >& Weights); FLOAT GetLayerWeightAtLocation( const FVector& InLocation, FName InLayerName, TArray* LayerCache=NULL ); /** Return the LandscapeHeightfieldCollisionComponent matching this component */ ULandscapeHeightfieldCollisionComponent* GetCollisionComponent() const; #endif #if __TW_PRECOMPUTED_VISIBILITY_ virtual void InvalidatePrecomputedVisibility() { MarkPrecomputedVisibilityRequiringRebuild(); } #endif friend class FLandscapeComponentSceneProxy; friend struct FLandscapeComponentDataInterface; INT GetLODBias(FLOAT HeightThreshold); // Calculate LOD Bias based on heightmap complexity void SetLOD(UBOOL bForced, INT InLODValue); } defaultproperties { `if(`__TW_LIGHTING_MODIFICATIONS_) // Landscape lighting channels are toggled per actor // Do not assign lighting channesl per component bOverrideAutoLightingChannels=TRUE `else LightingChannels=(Static=TRUE,bInitialized=TRUE) `endif CollideActors=TRUE BlockActors=TRUE BlockZeroExtent=TRUE BlockNonZeroExtent=TRUE BlockRigidBody=TRUE CastShadow=TRUE bAcceptsLights=TRUE bAcceptsDecals=TRUE bAcceptsStaticDecals=TRUE bUsePrecomputedShadows=TRUE bForceDirectLightMap=TRUE bUseAsOccluder=TRUE bAllowCullDistanceVolume=FALSE CollisionMipLevel=0 bNeedPostUndo=FALSE LODBias=0 ForcedLOD=-1 NeighborLOD[0]=255 NeighborLOD[1]=255 NeighborLOD[2]=255 NeighborLOD[3]=255 NeighborLOD[4]=255 NeighborLOD[5]=255 NeighborLOD[6]=255 NeighborLOD[7]=255 NeighborLODBias[0]=128 NeighborLODBias[1]=128 NeighborLODBias[2]=128 NeighborLODBias[3]=128 NeighborLODBias[4]=128 NeighborLODBias[5]=128 NeighborLODBias[6]=128 NeighborLODBias[7]=128 `if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) bAllowPersistentSplatters=TRUE `endif }