1using System.Runtime.CompilerServices;
63 public virtual void Log() {
91 " LightPropagate: {0:0.0}ms ({1}x) {2} ls",
105 " AllVertices: {0:0.0}ms ({1}x)",
232 m_updateParameters.Chunks = [];
233 m_updateParameters.Locations = [];
234 m_threadUpdateParameters.Chunks = [];
235 m_threadUpdateParameters.Locations = [];
257 contentDistance =
MathUtils.
Max(contentDistance, visibilityDistance);
259 if (contentDistance != value.ContentDistance
260 || visibilityDistance != value.VisibilityDistance
261 || !value.LastChunksUpdateCenter.HasValue
263 value.Center = center;
264 value.VisibilityDistance = visibilityDistance;
265 value.ContentDistance = contentDistance;
266 value.LastChunksUpdateCenter = center;
275 public virtual float GetUpdateProgress(
int locationIndex,
float visibilityDistance,
float contentDistance) {
283 float v =
MathUtils.
Max(visibilityDistance, contentDistance);
286 for (
int i = point.
X; i <= point2.
X; i++) {
287 for (
int j = point.
Y; j <= point2.
Y; j++) {
294 if (chunkAtCoords ==
null
302 else if (num5 <= num4) {
303 if (chunkAtCoords ==
null
313 return num2 <= 0 ? 1f : num / (float)(num2 + num);
327 m_terrain.SeasonTemperature = num;
328 m_terrain.SeasonHumidity = num2;
341 &&
Time.
RealTime - realTime < 0.0099999997764825821) { }
343 else if (
m_task ==
null) {
355 if (pendingLocation.Value.HasValue) {
363 m_updateParameters.Chunks =
m_terrain.AllocatedChunks;
383 foreach (
TerrainChunk terrainChunk
in allocatedChunks) {
386 terrainChunk.AreBehaviorsNotified =
true;
396 if (list.Count > 0) {
417 for (
int i = -radius; i <= radius; i++) {
418 for (
int j = -radius; j <= radius; j++) {
420 if (chunkAtCoords ==
null) {
423 if (chunkAtCoords.
State > state) {
424 chunkAtCoords.State = state;
425 if (forceGeometryRegeneration) {
429 chunkAtCoords.WasDowngraded =
true;
436 foreach (
TerrainChunk terrainChunk
in allocatedChunks) {
437 if (terrainChunk.
State > state) {
438 terrainChunk.State = state;
439 if (forceGeometryRegeneration) {
443 terrainChunk.WasDowngraded =
true;
451 for (
int i = 0; i < locations.Length; i++) {
462 foreach (
TerrainChunk terrainChunk
in allocatedChunks) {
464 bool noToFree =
false;
468 modLoader.ToFreeChunks(
this, terrainChunk, out
bool keepWorking);
469 noToFree |= keepWorking;
484 for (
int j = 0; j < locations.Length; j++) {
487 for (
int k = point.
X; k <= point2.
X; k++) {
488 for (
int l = point.
Y; l <= point2.
Y; l++) {
491 if (chunkAtCoords ==
null) {
499 else if (chunkAtCoords.
Coords.
X != k
500 || chunkAtCoords.
Coords.
Y != l) {
501 Log.
Error(
"Chunk wraparound detected at {0}", chunkAtCoords.
Coords);
509 bool modification = modLoader.ToAllocateChunks(
this, locations);
510 result |= modification;
522 terrainChunk.DowngradedState = terrainChunk.
State;
523 terrainChunk.WasDowngraded =
false;
529 terrainChunk.UpgradedState =
null;
539 terrainChunk.DowngradedState =
null;
542 terrainChunk.UpgradedState = terrainChunk.
ThreadState;
544 terrainChunk.WasUpgraded =
false;
562 catch (Exception e) {
577 if (terrainChunk !=
null) {
597 float num =
float.MaxValue;
604 for (
int j = 0; j < array.Length; j++) {
607 if (num2 <=
MathUtils.
Sqr(array[j].VisibilityDistance)) {
610 result = terrainChunk;
616 result = terrainChunk;
622 m_statistics.FindBestChunkTime += realTime2 - realTime;
632 viewPosition + 6f * viewDirection,
633 viewPosition + 6f * viewDirection - 6f * vector,
634 viewPosition + 6f * viewDirection + 6f * vector,
635 viewPosition + 6f * viewDirection - 2f * v,
636 viewPosition + 6f * viewDirection + 2f * v
638 List<TerrainChunk> list = [];
640 foreach (
Vector3 vector2
in array) {
642 if (chunkAtCell !=
null
644 && !list.Contains(chunkAtCell)) {
645 list.Add(chunkAtCell);
657 chunk.WasUpgraded =
true;
659 chunk.IsLoaded =
true;
661 m_statistics.LoadingTime += realTime20 - realTime19;
665 chunk.WasUpgraded =
true;
673 chunk.WasUpgraded =
true;
676 m_statistics.ContentsTime1 += realTime18 - realTime17;
683 chunk.WasUpgraded =
true;
686 m_statistics.ContentsTime2 += realTime16 - realTime15;
693 chunk.WasUpgraded =
true;
696 m_statistics.ContentsTime3 += realTime14 - realTime13;
703 "OnTerrainContentsGenerated",
705 modLoader.OnTerrainContentsGenerated(chunk);
710 chunk.WasUpgraded =
true;
713 m_statistics.ContentsTime4 += realTime8 - realTime7;
720 chunk.WasUpgraded =
true;
723 m_statistics.LightTime += realTime4 - realTime3;
727 for (
int i = -1; i <= 1; i++) {
728 for (
int j = -1; j <= 1; j++) {
730 if (chunkAtCoords !=
null
738 m_lightSources.Count = 0;
746 m_statistics.LightSourcesTime += realTime10 - realTime9;
750 chunk.WasUpgraded =
true;
754 m_statistics.LightPropagateTime += realTime12 - realTime11;
758 for (
int k = -1; k <= 1; k++) {
759 for (
int l = -1; l <= 1; l++) {
761 if (chunkAtCoords2 !=
null
771 chunk.NewGeometryData =
false;
774 "GenerateChunkVertices",
776 modLoader.GenerateChunkVertices(chunk,
true);
782 chunk.WasUpgraded =
true;
785 m_statistics.VerticesTime1 += realTime6 - realTime5;
793 "GenerateChunkVertices",
795 modLoader.GenerateChunkVertices(chunk,
true);
799 chunk.NewGeometryData =
true;
802 chunk.WasUpgraded =
true;
806 m_statistics.VerticesTime2 += realTime2 - realTime;
832 while (num4 <= num + 1) {
844 int num7 = skylightValue;
848 while (num4 >= num2) {
866 while (num4 >= num2) {
882 "GenerateChunkLightSources",
895 int k = bottomHeightFast;
897 while (k <= topHeightFast) {
904 if (emittedLightAmount > 1) {
916 if (chunkAtCell !=
null
917 && chunkAtCell2 !=
null
918 && chunkAtCell3 !=
null
919 && chunkAtCell4 !=
null) {
920 int num4 = num - 1 - chunkAtCell.
Origin.
X;
921 int num5 = num2 - chunkAtCell.
Origin.
Y;
922 int num6 = num + 1 - chunkAtCell2.
Origin.
X;
923 int num7 = num2 - chunkAtCell2.
Origin.
Y;
924 int num8 = num - chunkAtCell3.
Origin.
X;
925 int num9 = num2 - 1 - chunkAtCell3.
Origin.
Y;
926 int num10 = num - chunkAtCell4.
Origin.
X;
927 int num11 = num2 + 1 - chunkAtCell4.
Origin.
Y;
935 while (l <= topHeightFast) {
943 int num18 =
MathUtils.
Max(cellLightFast, cellLightFast2, cellLightFast3, cellLightFast4)
990 if (terrainChunk ==
null
1013 int num5 = num + chunk.
Origin.
X;
1014 int num6 = num2 + chunk.
Origin.
Y;
1021 if (blocks[num9].IsTransparent_(cellValueFast)) {
1024 if (num11 > num10) {
1037 if (chunkAtCell ==
null) {
1054 for (
int i = 0; i < m_lightSources.Count && i < 120000; i++) {
1056 int light = lightSource.
Light;
1060 if (lightSource.
Y > 0) {
1070 for (
int i = 0; i < m_lightSources.Count && i < 120000; i++) {
1072 int light = lightSource.
Light;
1073 int x = lightSource.
X;
1074 int y = lightSource.
Y;
1075 int z = lightSource.
Z;
1114 if (chunk !=
null) {
1145 if (chunkAtCoords4 ==
null) {
1148 if (chunkAtCoords2 ==
null) {
1151 if (chunkAtCoords5 ==
null) {
1154 if (chunkAtCoords7 ==
null) {
1158 if (index % 2 == stage) {
1160 if (generateHash != 0
1168 if (geometry ==
null) {
1173 for (
int x1 = num1; x1 < num3; ++x1) {
1174 for (
int z1 = num2; z1 < num4; ++z1) {
1177 if ((z1 == 0 && chunkAtCoords1 ==
null)
1183 if ((z1 == 0 && chunkAtCoords3 ==
null)
1204 for (
int y = num5; y < num6; ++y) {
1207 if (contents != 0) {
1238 int startOriginX = chunk.Origin.X - 1;
1240 int startOriginY = chunk.Origin.Y - 1;
1242 for (
int originX = startOriginX; originX < endOriginX; originX++) {
1243 for (
int originY = startOriginY; originY < endOriginY; originY++) {
1245 if (chunkAtCell !=
null) {
1251 int neighborBottomHeight1 = x > 0
1253 :
m_terrain.GetBottomHeight(originX - 1, originY);
1254 int neighborBottomHeight2 = z > 0
1256 :
m_terrain.GetBottomHeight(originX, originY - 1);
1259 :
m_terrain.GetBottomHeight(originX + 1, originY);
1262 :
m_terrain.GetBottomHeight(originX, originY + 1);
1264 MathUtils.
Min(neighborBottomHeight1, neighborBottomHeight2, neighborBottomHeight3, neighborBottomHeight4),
1267 int topHeight2 = topHeight + 2;
1277 for (
int slice = startSlice; slice <= endSlice; slice++) {
1282 int endCellIndex = cellIndex + endY - startY;
1283 while (cellIndex < endCellIndex) {
1296 m_statistics.HashTime += realTime2 - realTime;
1304 bool isLoaded = chunk.IsLoaded;
1307 int x = i + chunk.Origin.X;
1308 int z = j + chunk.Origin.Y;
1312 int cellValueFast = chunk.GetCellValueFast(num);
1314 if (contents != 0) {
1316 for (
int k = 0; k < blockBehaviors.Length; k++) {
1335 if (name ==
"Brightness") {
Silk.NET.Windowing.Monitor Monitor
static void Error(object message)
static void Information(object message)
static int Min(int x1, int x2)
static int Max(int x1, int x2)
virtual bool IsTransparent_(int value)
int DefaultEmittedLightAmount
void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
生成地形顶点(用于绘制放置的方块)
virtual int GetEmittedLightAmount(int value)
static Action< string > SettingChanged
static bool MultithreadedTerrainUpdate
virtual void OnChunkInitialized(TerrainChunk chunk)
virtual void OnBlockGenerated(int value, int x, int y, int z, bool isLoaded)
virtual void OnChunkDiscarding(TerrainChunk chunk)
virtual void SetSunlightHeightFast(int x, int z, int sunlightHeight)
static int CalculateCellIndex(int x, int y, int z)
TerrainChunkState? DowngradedState
int[] GeneratedSliceContentsHashes
int[] SliceContentsHashes
virtual int GetCellValueFast(int index)
virtual void SetCellValueFast(int x, int y, int z, int value)
TerrainChunkState ThreadState
virtual int GetBottomHeightFast(int x, int z)
virtual int GetTopHeightFast(int x, int z)
TerrainGeometry[] ChunkSliceGeometries
TerrainChunkState? UpgradedState
virtual void SetTopHeightFast(int x, int z, int topHeight)
virtual int GetCellLightFast(int x, int y, int z)
virtual int GetShaftValueFast(int x, int z)
virtual void InvalidateSliceContentsHashes()
TerrainChunkGeometry Geometry
bool AreBehaviorsNotified
virtual void SetBottomHeightFast(int x, int z, int bottomHeight)
virtual void ClearGeometry()
static Point2 ToChunk(Vector2 p)
static int ExtractTemperature(int value)
static int ExtractContents(int value)
static int ToCell(float x)
static int ExtractBottomHeight(int value)
static int ExtractLight(int value)
static int ExtractHumidity(int value)
static int ExtractTopHeight(int value)
virtual TerrainChunk GetChunkAtCoords(int chunkX, int chunkZ)
static int ReplaceLight(int value, int light)
static int ExtractSunlightHeight(int value)
double LightPropagateTime
int LightSourceInstancesCount
virtual float GetUpdateProgress(int locationIndex, float visibilityDistance, float contentDistance)
TerrainUpdater(SubsystemTerrain subsystemTerrain)
const float m_updateHysteresis
ManualResetEvent m_pauseEvent
SubsystemGameInfo m_subsystemGameInfo
UpdateParameters m_updateParameters
virtual TerrainChunk FindBestChunkToUpdate(out TerrainChunkState desiredState)
static bool LogTerrainUpdateStats
bool m_unpauseUpdateThread
virtual void PrepareForDrawing(Camera camera)
virtual void GenerateChunkVertices(TerrainChunk chunk, int stage)
virtual bool SendReceiveChunkStates()
SubsystemBlockBehaviors m_subsystemBlockBehaviors
virtual void PropagateLightSources()
const int m_lightAttenuationWithDistance
virtual List< TerrainChunk > DetermineSynchronousUpdateChunks(Vector3 viewPosition, Vector3 viewDirection)
virtual bool SynchronousUpdateFunction()
Action< TerrainChunk > ChunkInitialized
object m_updateParametersLock
SubsystemTerrain m_subsystemTerrain
virtual void NotifyBlockBehaviors(TerrainChunk chunk)
SubsystemAnimatedTextures m_subsystemAnimatedTextures
virtual void DowngradeChunkNeighborhoodState(Point2 coordinates, int radius, TerrainChunkState state, bool forceGeometryRegeneration)
virtual void PropagateLightSource(int x, int y, int z, int light)
virtual void UpdateChunkSingleStep(TerrainChunk chunk, int skylightValue)
AutoResetEvent m_updateEvent
static int SlowTerrainUpdate
virtual void SetUpdateLocation(int locationIndex, Vector2 center, float visibilityDistance, float contentDistance)
virtual void ThreadUpdateFunction()
SubsystemSeasons m_subsystemSeasons
static bool IsChunkInRange(Vector2 chunkCenter, UpdateLocation[] locations)
virtual void GenerateChunkLightSources(TerrainChunk chunk)
virtual void GenerateChunkSunLightAndHeight(TerrainChunk chunk, int skylightValue)
AutoResetEvent UpdateEvent
int m_synchronousUpdateFrame
FloatCurve TemperatureCurve
virtual void PropagateLightSource(TerrainChunk chunk, int x, int y, int z, int light)
virtual void SendReceiveChunkStatesThread()
SubsystemSky m_subsystemSky
virtual void SettingsManager_SettingChanged(string name)
virtual void CalculateChunkSliceContentsHashes(TerrainChunk chunk)
virtual void RemoveUpdateLocation(int locationIndex)
UpdateParameters m_threadUpdateParameters
UpdateStatistics m_statistics
virtual void RequestSynchronousUpdate()
static bool IsChunkInRange(Vector2 chunkCenter, ref UpdateLocation location)
volatile bool m_quitUpdateThread
Dictionary< int, UpdateLocation?> m_pendingLocations
virtual void GenerateChunkEdgeLightSources(TerrainChunk chunk, int face)
virtual void UnpauseUpdateThread()
DynamicArray< LightSource > m_lightSources
virtual bool AllocateAndFreeChunks(UpdateLocation[] locations)
virtual void DowngradeAllChunksState(TerrainChunkState state, bool forceGeometryRegeneration)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static float DistanceSquared(Vector2 v1, Vector2 v2)
static Vector3 Cross(Vector3 v1, Vector3 v2)
static Vector3 Normalize(Vector3 v)
static readonly Vector3 UnitY
Vector2? LastChunksUpdateCenter
Dictionary< int, UpdateLocation > Locations