140 lines
5.2 KiB
C++
140 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Landscape.h"
|
|
#include "Importer.h"
|
|
|
|
namespace Lightmass
|
|
{
|
|
// Accessors from FLandscapeDataInterface
|
|
void FLandscapeStaticLightingMesh::VertexIndexToXY(int32 VertexIndex, int32& OutX, int32& OutY) const
|
|
{
|
|
OutX = VertexIndex % NumVertices;
|
|
OutY = VertexIndex / NumVertices;
|
|
}
|
|
|
|
void FLandscapeStaticLightingMesh::QuadIndexToXY(int32 QuadIndex, int32& OutX, int32& OutY) const
|
|
{
|
|
OutX = QuadIndex % NumQuads;
|
|
OutY = QuadIndex / NumQuads;
|
|
}
|
|
|
|
const FColor* FLandscapeStaticLightingMesh::GetHeightData( int32 LocalX, int32 LocalY ) const
|
|
{
|
|
return &HeightMap[LocalX + LocalY * NumVertices ];
|
|
}
|
|
|
|
void FLandscapeStaticLightingMesh::GetTriangleIndices(int32 QuadIndex,int32 TriNum,int32& OutI0,int32& OutI1,int32& OutI2) const
|
|
{
|
|
//OutI0 = 0; OutI1 = 1; OutI2 = 2;
|
|
int32 QuadX, QuadY;
|
|
QuadIndexToXY( QuadIndex, QuadX, QuadY );
|
|
switch(TriNum)
|
|
{
|
|
case 0:
|
|
OutI0 = (QuadX + 0) + (QuadY + 0) * NumVertices;
|
|
OutI1 = (QuadX + 1) + (QuadY + 1) * NumVertices;
|
|
OutI2 = (QuadX + 1) + (QuadY + 0) * NumVertices;
|
|
break;
|
|
case 1:
|
|
OutI0 = (QuadX + 0) + (QuadY + 0) * NumVertices;
|
|
OutI1 = (QuadX + 0) + (QuadY + 1) * NumVertices;
|
|
OutI2 = (QuadX + 1) + (QuadY + 1) * NumVertices;
|
|
break;
|
|
}
|
|
|
|
if (bReverseWinding)
|
|
{
|
|
Swap(OutI1, OutI2);
|
|
}
|
|
}
|
|
|
|
// from FStaticLightMesh....
|
|
void FLandscapeStaticLightingMesh::GetStaticLightingVertex(int32 VertexIndex, FStaticLightingVertex& OutVertex) const
|
|
{
|
|
int32 X, Y;
|
|
VertexIndexToXY(VertexIndex, X, Y);
|
|
|
|
const int32 LocalX = X - ExpandQuadsX;
|
|
const int32 LocalY = Y - ExpandQuadsY;
|
|
|
|
const FColor* Data = GetHeightData( X, Y );
|
|
|
|
OutVertex.WorldTangentZ.X = 2.0f / 255.f * (float)Data->B - 1.0f;
|
|
OutVertex.WorldTangentZ.Y = 2.0f / 255.f * (float)Data->A - 1.0f;
|
|
OutVertex.WorldTangentZ.Z = FMath::Sqrt(FMath::Max(1.0f - (FMath::Square(OutVertex.WorldTangentZ.X) + FMath::Square(OutVertex.WorldTangentZ.Y)), 0.f));
|
|
OutVertex.WorldTangentX = FVector4f(OutVertex.WorldTangentZ.Z, 0.0f, -OutVertex.WorldTangentZ.X);
|
|
OutVertex.WorldTangentY = OutVertex.WorldTangentZ ^ OutVertex.WorldTangentX;
|
|
|
|
// Copied (vaguely) from FLandscapeComponentDataInterface::GetWorldPositionTangents to fix bad lighting when rotated
|
|
const FMatrix44f LtWNoScale = LocalToWorld.GetMatrixWithoutScale();
|
|
OutVertex.WorldTangentX = LtWNoScale.TransformVector(OutVertex.WorldTangentX);
|
|
OutVertex.WorldTangentY = LtWNoScale.TransformVector(OutVertex.WorldTangentY);
|
|
OutVertex.WorldTangentZ = LtWNoScale.TransformVector(OutVertex.WorldTangentZ);
|
|
|
|
const uint16 Height = (Data->R << 8) + Data->G;
|
|
OutVertex.WorldPosition = LocalToWorld.TransformPosition( FVector4f( LocalX, LocalY, ((float)Height - 32768.f) * LANDSCAPE_ZSCALE ) );
|
|
//UE_LOG(LogLightmass, Log, TEXT("%d, %d, %d, %d, %d, %d, X:%f, Y:%f, Z:%f "), SectionBaseX + LocalX - ExpandQuadsX, SectionBaseY + LocalY - ExpandQuadsY, ClampedLocalX, ClampedLocalY, SectionBaseX, SectionBaseY, WorldPos.X, WorldPos.Y, WorldPos.Z);
|
|
|
|
const int32 LightmapUVIndex = 1;
|
|
|
|
OutVertex.TextureCoordinates[0] = FVector2f((float)X / NumVertices, (float)Y / NumVertices);
|
|
OutVertex.TextureCoordinates[LightmapUVIndex].X = X * UVFactor;
|
|
OutVertex.TextureCoordinates[LightmapUVIndex].Y = Y * UVFactor;
|
|
}
|
|
|
|
// FStaticLightingMesh interface.
|
|
void FLandscapeStaticLightingMesh::GetTriangle(int32 TriangleIndex,FStaticLightingVertex& OutV0,FStaticLightingVertex& OutV1,FStaticLightingVertex& OutV2,int32& ElementIndex) const
|
|
{
|
|
int32 I0, I1, I2;
|
|
//GetTriangleIndices(TriangleIndex,I0, I1, I2);
|
|
I0 = I1 = I2 = 0;
|
|
int32 QuadIndex = TriangleIndex >> 1;
|
|
int32 QuadTriIndex = TriangleIndex & 1;
|
|
|
|
GetTriangleIndices(QuadIndex, QuadTriIndex, I0, I1, I2);
|
|
GetStaticLightingVertex(I0,OutV0);
|
|
GetStaticLightingVertex(I1,OutV1);
|
|
GetStaticLightingVertex(I2,OutV2);
|
|
|
|
ElementIndex = 0;
|
|
}
|
|
|
|
void FLandscapeStaticLightingMesh::GetTriangleIndices(int32 TriangleIndex,int32& OutI0,int32& OutI1,int32& OutI2) const
|
|
{
|
|
//OutI0 = OutI1 = OutI2 = 0;
|
|
int32 QuadIndex = TriangleIndex >> 1;
|
|
int32 QuadTriIndex = TriangleIndex & 1;
|
|
|
|
GetTriangleIndices(QuadIndex, QuadTriIndex, OutI0, OutI1, OutI2);
|
|
}
|
|
|
|
void FLandscapeStaticLightingMesh::Import( class FLightmassImporter& Importer )
|
|
{
|
|
// import super class
|
|
FStaticLightingMesh::Import( Importer );
|
|
Importer.ImportData((FLandscapeStaticLightingMeshData*) this);
|
|
|
|
// we have the guid for the mesh, now hook it up to the actual static mesh
|
|
int32 ReadSize = FMath::Square(ComponentSizeQuads + 2*ExpandQuadsX + 1);
|
|
checkf(ReadSize > 0, TEXT("Failed to import Landscape Heightmap data!"));
|
|
Importer.ImportArray(HeightMap, ReadSize);
|
|
check(HeightMap.Num() == ReadSize);
|
|
|
|
NumVertices = ComponentSizeQuads + 2*ExpandQuadsX + 1;
|
|
NumQuads = NumVertices - 1;
|
|
UVFactor = LightMapRatio / NumVertices;
|
|
bReverseWinding = (LocalToWorld.RotDeterminant() < 0.0f);
|
|
}
|
|
|
|
void FLandscapeStaticLightingTextureMapping::Import( class FLightmassImporter& Importer )
|
|
{
|
|
FStaticLightingTextureMapping::Import(Importer);
|
|
|
|
// Can't use the FStaticLightingMapping Import functionality for this
|
|
// as it only looks in the StaticMeshInstances map...
|
|
Mesh = Importer.GetLandscapeMeshInstances().FindRef(Guid);
|
|
check(Mesh);
|
|
}
|
|
|
|
} //namespace Lightmass
|