Files
UnrealEngine/Engine/Plugins/Experimental/Water/Source/Runtime/Private/BakedShallowWaterSimulationComponent.cpp
2025-05-18 13:04:45 +08:00

90 lines
3.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "BakedShallowWaterSimulationComponent.h"
#include "WaterBodyActor.h"
void FShallowWaterSimulationGrid::SampleShallowWaterSimulationAtIndex(const FVector2D &QueryFloatIndex, FVector& OutWaterVelocity, float& OutWaterHeight, float& OutWaterDepth) const
{
OutWaterHeight = 0;
OutWaterDepth = 0;
OutWaterVelocity = FVector(0, 0, 0);
if (QueryFloatIndex.X > 0 && QueryFloatIndex.X < NumCells.X - 1 && QueryFloatIndex.Y > 0 && QueryFloatIndex.Y < NumCells.Y - 1)
{
const FIntVector2 BaseIndex = FIntVector2(QueryFloatIndex.X, QueryFloatIndex.Y);
const FVector2D LerpValue = QueryFloatIndex - FVector2D(BaseIndex.X, BaseIndex.Y);
const FVector4 Sample00 = ArrayValues[(BaseIndex.X + 0) + (BaseIndex.Y + 0) * NumCells.X];
const FVector4 Sample10 = ArrayValues[(BaseIndex.X + 1) + (BaseIndex.Y + 0) * NumCells.X];
const FVector4 Sample01 = ArrayValues[(BaseIndex.X + 0) + (BaseIndex.Y + 1) * NumCells.X];
const FVector4 Sample11 = ArrayValues[(BaseIndex.X + 1) + (BaseIndex.Y + 1) * NumCells.X];
const FVector4 Sample0 = Sample00 * (1. - LerpValue.X) + Sample10 * (LerpValue.X);
const FVector4 Sample1 = Sample01 * (1. - LerpValue.X) + Sample11 * (LerpValue.X);
const FVector4 Sample = Sample0 * (1. - LerpValue.Y) + Sample1 * (LerpValue.Y);
OutWaterHeight = Sample.X + Position.Z;
OutWaterDepth = Sample.Y;
OutWaterVelocity = FVector(Sample.Z, Sample.W, 0);
}
}
void FShallowWaterSimulationGrid::QueryShallowWaterSimulationAtIndex(const FIntVector2 &QueryIndex, FVector& OutWaterVelocity, float& OutWaterHeight, float& OutWaterDepth) const
{
OutWaterHeight = 0;
OutWaterDepth = 0;
OutWaterVelocity = FVector(0,0,0);
if (QueryIndex.X >= 0 && QueryIndex.X < NumCells.X && QueryIndex.Y >= 0 && QueryIndex.Y < NumCells.Y)
{
const FVector4 Sample = ArrayValues[QueryIndex.X + QueryIndex.Y * NumCells.X];
OutWaterHeight = Sample.X + Position.Z;
OutWaterDepth = Sample.Y;
OutWaterVelocity = FVector(Sample.Z, Sample.W, 0);
}
}
FVector FShallowWaterSimulationGrid::ComputeShallowWaterSimulationNormalAtPosition(const FVector &QueryPos) const
{
const FVector2D FloatIndexPos = WorldToFloatIndex(QueryPos);
float HRight;
float HUp;
float H;
float Depth;
float DepthRight;
float DepthUp;
FVector VelocityIGNORE;
FVector Normal(0, 0, 1);
SampleShallowWaterSimulationAtIndex(FloatIndexPos + FVector2D::ZeroVector, VelocityIGNORE, H, Depth);
SampleShallowWaterSimulationAtIndex(FloatIndexPos + FVector2D(1,0), VelocityIGNORE, HRight, DepthRight);
SampleShallowWaterSimulationAtIndex(FloatIndexPos + FVector2D(0, 1), VelocityIGNORE, HUp, DepthUp);
FVector WorldPos = FloatIndexToWorld(FloatIndexPos + FVector2D::ZeroVector);
FVector WorldPosRight = FloatIndexToWorld(FloatIndexPos + FVector2D(1, 0));
FVector WorldPosUp = FloatIndexToWorld(FloatIndexPos + FVector2D(0, 1));
WorldPos.Z += H;
WorldPosRight.Z += HRight;
WorldPosUp.Z += HUp;
const FVector CrossProd = (WorldPosRight - WorldPos).Cross(WorldPosUp - WorldPos);
const float CrossProdLength = CrossProd.Length();
// default to upward facing normal
if (CrossProdLength > SMALL_NUMBER)
{
Normal = CrossProd / CrossProdLength;
}
return Normal;
}
UBakedShallowWaterSimulationComponent::UBakedShallowWaterSimulationComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{}