Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > Blitz3D > 3D-программирование

3D-программирование Вопросы, касающиеся программирования 3D мира

Ответ
 
Опции темы
Старый 10.06.2007, 09:20   #1
Matt Merkulov
Модератор
 
Аватар для Matt Merkulov
 
Регистрация: 23.10.2005
Сообщений: 219
Написано 62 полезных сообщений
(для 247 пользователей)
Реализовал много травы

Продолжение этой ветки:
http://www.boolean.name/showthread.php?t=3604

Diplomat таки был прав в том, что генерация квадратов травы (или кустов) заранее - более предпочтительный метод. Все верно - если травяные квадраты относительно маленькие, то их создание и модификация занимают некоторое время (небольшое, впрочем). Если квадраты большие (что положительно сказывается на FPS), то, с учетом наложения на неровную поверхность ландшафта, все начинает выглядеть крайне коряво - трава висит в воздухе / тонет под землей и отчетливо видна "травяная плоскость". Если кусты перемещать, то, думаю, прирост скорости будет незначительный, а к этим проблемам добавится необходимость возиться с реализацией неоднородной плотности травы (под водой, например, ее быть не должно) и будет сложно реализовать разные виды травы в разных областях.

Однако, тема еще не раскрыта - возникают дополнительные вопросы:
1) При большом размере квадратов возникает эффект "травяных пашен", когда отчетливо видно, что трава появляется квадратными участками. Я частично решил эту проблему, сделав вместо квадратных участков круглые, покрывающие полностью квадрат. Думаю, можно поэкспериментировать с изменением формы и частичным взаимным перекрыванием участков, добившись лучшего результата.
2) Какой оптимальный размер для квадратов? При маленьком уменьшается FPS, зато трава появляется красивой ровной круглой областью. Я реализовал возможность изменения размеров (пока в константах).
3) Каким установить время проявления новых участков? Небольшим - трава будет резко появляться, малым - кол-во видимых участков увеличится, что отрицательно скажется на FPS.
4) Как быть с прозрачностью? Сортировка замедляет рендеринг, а иначе появляются артефакты. Впрочем, они незначительны, более неприятен эффект "переключения куста", когда он становится полностью видимым.

Оба способа - пре-генерация и появление квадратов (попробуйте оба метода с большими и маленькими квадратами). Есть возможность включить отображение метода распространения активных квадратов (Paint = True).

SeedRnd MilliSecs()

Const MethodCreate = 0
Const MethodHide = 1

Const LandscapeSize = 256
Const DitheringTextureSize = 512
Const DitheringTextureScale = 4
Const LandscapeSizeMask = LandscapeSize - 1
Const LandscapeHeight# = 32

Const GrassColor = 100
Const GrassDColor = 20
Const GrassBackground = 100
Const MaxGrassSpreadingRadius# = 0.72

Const BushesThreshold# = 0.28
Const MaxBushesThreshold# = 0.34
Const SandThreshold# = 0.3
Const HillsMinRadius = 16
Const HillsMaxRadius = 64
Const HillsMinHeight# = 0.2
Const HillsMaxHeight# = 1.0
Const HillsQuantity# = 100

Const BushTypesQuantity = 2
Const BushModelsQuantity = 2
Const BushTextureSize = 256

Const BushModelScaleMin# = 0.3
Const BushModelScaleMax# = 0.6

Const GrassSquareModelsQuantity = 40
Const BushesDensityLevelsQuantity = 4

Const PlayerHeight# = 1.5
Const PlayerSpeedPerSecond# = 10.0
Const PlayerTurnPerSecond# = 180.0

Const FadingTimeInSeconds# = 1.0
Const MaxAlpha# = 1.0


;Const GrassMethod = MethodCreate ; Generation of some grass
Const GrassMethod = MethodHide ; Pre - generating of grass squares


;Small grass quadrants - smooth, but slow grass rendering
;Const GrassGridCellSize# = 2.0
;Const BushesQuantityMultiplier = 3
;Const GrassRadius# = 8


;Largel grass quadrants - jerky, but fast grass rendering
Const GrassGridCellSize# = 8.0
Const BushesQuantityMultiplier = 48
Const GrassRadius# = 2


Const Paint = False
;Const Paint = True


Const GrassGridSize = LandscapeSize / GrassGridCellSize#
Const BushTextureXTexSize# = 1.0 / BushTypesQuantity
Const BushTextureYTexSize# = 1.0 / BushModelsQuantity

Graphics3D 800, 600
Camera = CreateCamera()
ScaleEntity camera, 0.3, 0.3, 0.3
PositionEntity Camera, LandscapeSize / 2, 100, LandscapeSize / 2
;RotateEntity Camera, 45, 0, 0
RotateEntity CreateLight(), 45, 45, 0


Type ActiveSquare
	Field X, Z, JustAdded
End Type

Type FadingBush
	Field Alpha#, FadingMode, X, Z
End Type

Dim ServiceMap(LandscapeSize, LandscapeSize)
Const VisibleActiveSquare = %11
Const InvisibleActiveSquare = %10
Const VisibleSquare = %01
Const InvisibleSquare = %00
Const Visibility = %01
Const Activity = %10

Dim BushModel(BushTypesQuantity - 1, BushModelsQuantity - 1)
Dim GrassSquareModel(GrassSquareModelsQuantity - 1, BushesDensityLevelsQuantity - 1)
Dim BushQuantityMap#(GrassGridSize - 1, GrassGridSize - 1)
Dim BushMap(GrassGridSize - 1, GrassGridSize - 1)
Dim BushFader.FadingBush(GrassGridSize - 1, GrassGridSize - 1)

Global Landscape = CreateTerrain(LandscapeSize)
Global LandscapeTexture = CreateTexture(LandscapeSize, LandscapeSize, 15)
Global LandscapeDitheringTexture = CreateTexture(DitheringTextureSize, DitheringTextureSize, 15)
Global Grass = CreateTexture(BushTextureSize * BushTypesQuantity, BushTextureSize * BushModelsQuantity, 13)
ScaleEntity Landscape, 1, LandscapeHeight#, 1

CreateLandscape

CreateBushes

PaintTextures

TryToAddSquare EntityX(Camera) / GrassGridCellSize#, EntityZ(Camera) / GrassGridCellSize#

Const FadingIn = 1, FadingOut = 2

Repeat
	MoveEntity Camera, 0, 0, PrevFrameRenderingTimeInSeconds# * PlayerSpeedPerSecond# * (KeyDown(200) - KeyDown(208))
	TurnEntity Camera, 0, PrevFrameRenderingTimeInSeconds# * PlayerTurnPerSecond# * (KeyDown(203) - KeyDown(205)), 0

	FrameBeginningTime = MilliSecs()

	PlayerX# = EntityX(Camera)
	PlayerZ# = EntityZ(Camera)
	PositionEntity Camera, PlayerX#, TerrainY#(Landscape, PlayerX#, 0, PlayerZ#) + PlayerHeight#, PlayerZ#

	SetBuffer TextureBuffer(LandscapeTexture)

	qua = 0
	For S.ActiveSquare=Each ActiveSquare
		tmp = ServiceMap(S\X, S\Z)
		If (ServiceMap(S\X, S\Z) And Activity) = Activity And S\JustAdded Then
		 	Delete S
		Else
			DX# = S\X - PlayerX# / GrassGridCellSize#
			DZ# = S\Z - PlayerZ# / GrassGridCellSize#
			Distance# = Sqr(DX# * DX# + DZ# * DZ#)
			S\JustAdded = False
			If Distance# > GrassRadius# Then
				If (ServiceMap(S\X, S\Z) And Visibility) = VisibleSquare Then
					ExpandSquare S
					If Paint Then WritePixel S\X * GrassGridCellSize#, S\Z * GrassGridCellSize#, $FF00FFFF
					If BushMap(S\X, S\Z) Or GrassMethod = MethodHide Then
						If BushFader(S\X, S\Z) <> Null Then
							FB.FadingBush = BushFader(S\X, S\Z)
						Else
							FB.FadingBush = New FadingBush
							FB\X = S\X
							FB\Z = S\Z
							FB\Alpha# = MaxAlpha#
							BushFader(S\X, S\Z) = FB
						End If
						FB\FadingMode = FadingOut
					End If
					ServiceMap(S\X, S\Z) = InvisibleActiveSquare
				Else
					If CountNeighbors(S, VisibleSquare) = 0 Then
						ServiceMap(S\X, S\Z) = InvisibleSquare
						If Paint Then WritePixel S\X * GrassGridCellSize#, S\Z * GrassGridCellSize#, $FF7F7F7F
						Delete S
					Else
						ServiceMap(S\X, S\Z) = InvisibleActiveSquare
					End If
				End If
			Else
				If (ServiceMap(S\X, S\Z) And Visibility) = InvisibleSquare Then
					ExpandSquare S
					If Paint Then WritePixel S\X * GrassGridCellSize#, S\Z * GrassGridCellSize#, $FFFF0000
					ServiceMap(S\X, S\Z) = VisibleActiveSquare
					S\JustAdded = False
					If GrassMethod = MethodHide Then
						ShowEntity BushMap(S\X, S\Z)
					Else
						BushQuantity = Floor(BushQuantityMap#(S\X, S\Z) - Rnd(1.0, 0.0001))
						If BushQuantity >= 0 And BushFader(S\X, S\Z) = Null Then
							E = CopyEntity(GrassSquareModel(Rand(0,GrassSquareModelsQuantity - 1), BushQuantity))
							LX# = S\X * GrassGridCellSize#
							LZ# = S\Z * GrassGridCellSize#
							H# = TerrainY(Landscape, LX#, 0, LZ#)
							DY1# = TerrainY(Landscape, LX# + 1.0, 0, LZ#) - H#
							DY2# = TerrainY(Landscape, LX#, 0, LZ# + 1.0) - H#
							AlignToVector E, -DY1#, 1.0, -DY2#, 2
							PositionEntity E, LX#, H#, LZ#
							BushMap(S\X, S\Z) = E
						Else
							BushMap(S\X, S\Z) = CreateMesh()
						End If
					End If
					If BushFader(S\X, S\Z) <> Null Then
						FB.FadingBush = BushFader(S\X, S\Z)
					Else
						FB.FadingBush = New FadingBush
						FB\X = S\X
						FB\Z = S\Z
						FB\Alpha# = 0.0
						BushFader(S\X, S\Z) = FB
					End If
					FB\FadingMode = FadingIn
				Else
					If CountNeighbors(S, InvisibleSquare) = 0 Then
						ServiceMap(S\X, S\Z) = VisibleSquare
						If Paint Then WritePixel S\X * GrassGridCellSize#, S\Z * GrassGridCellSize#, $FF7F7F7F
						Delete S
					Else
						ServiceMap(S\X, S\Z) = VisibleActiveSquare
					End If
				End If
			End If
		End If
	Next

	DFading# = PrevFrameRenderingTimeInSeconds# / FadingTimeInSeconds#
	For FB.FadingBush = Each FadingBush
		A# = FB\Alpha#
		If FB\FadingMode = FadingIn Then
			A# = A# + DFading#
			If A# > MaxAlpha# Then A# = MaxAlpha#
			FB\Alpha# = A#
			EntityAlpha BushMap(FB\X, FB\Z), A#
			If A# = MaxAlpha# Then Delete FB
		Else
			A# = A# - DFading#
			If A# < 0.0 Then A# = 0.0
			FB\Alpha# = A#
			EntityAlpha BushMap(FB\X, FB\Z), A#
			If A# = 0.0 Then
				If GrassMethod = MethodHide Then
					HideEntity BushMap(FB\X, FB\Z)
				Else
					FreeEntity BushMap(FB\X, FB\Z)
					BushMap(FB\X, FB\Z) = 0
				End If
				BushFader(FB\X, FB\Z) = Null
				Delete FB
			End If
		End If
	Next

	For S.ActiveSquare=Each ActiveSquare
		qua = qua + 1
	Next

	SetBuffer BackBuffer()
	
	RenderWorld

	;Stop

	If FPSCounterResetTime <= MilliSecs() Then
		FPSCounterResetTime = MilliSecs() + 1000
		FPS = FPSCounter
		FPSCounter = 0
	Else
		FPSCounter = FPSCounter + 1
	End If
	Text 0, 0, "Frames / sec:" + FPS + ", activesquares: " + qua

	Flip

	PrevFrameRenderingTimeInSeconds# = 0.001 * (MilliSecs() - FrameBeginningTime)
Until KeyHit(1)

For X = 0 To GrassGridSize - 1
	For Y = 0 To GrassGridSize - 1
		If BushMap(X, Y) Then FreeEntity BushMap(X, Y)
	Next
Next

FreeEntity Landscape
FreeTexture LandscapeTexture
FreeTexture LandscapeDitheringTexture

If GrassMethod = MethodCreate Then
	For n1 = 0 To GrassSquareModelsQuantity - 1
		For n2 = 0 To BushesDensityLevelsQuantity - 1
			FreeEntity GrassSquareModel(n1, n2)
		Next
	Next
End If

Function CreateLandscape()
	SetBuffer FrontBuffer()
	Text 0, 0, "Generating landscape..."
	For n = 1 To HillsQuantity
		HillRadius = Rnd(HillsMinRadius, HillsMaxRadius)
		HillX = Rand(0, LandscapeSize)
		HillY = Rand(0, LandscapeSize)
		HillHeight# = Rnd(HillsMinHeight#, HillsMaxHeight#)

		If -HillRadius < -HillX Then DXFrom = -HillX Else DXFrom = -HillRadius
		If HillRadius > LandscapeSize - HillX Then DXTo = LandscapeSize - HillX - 1 Else DXTo = HillRadius
		If -HillRadius < -HillY Then DYFrom = -HillY Else DYFrom = -HillRadius
		If HillRadius > LandscapeSize - HillY Then DYTo = LandscapeSize - HillY - 1 Else DYTo = HillRadius

		For DY = DYFrom To DYTo
			For DX = DXFrom To DXTo
				X = HillX + DX
				Y = HillY + DY
				K# = Sqr(DX * DX + DY * DY) / HillRadius
				If K# > 1.0 Then K# = 1.0
				Height# = 0.5 * (1.0 + Cos(180.0 * K#)) * HillHeight# * HillRadius / 64
				If Height# > TerrainHeight#(Landscape, X, Y) Then ModifyTerrain Landscape, X, Y, Height#
			Next
		Next
	Next

	SetBuffer FrontBuffer()
	Text 0, 10, "Painting landscape..."
	SetBuffer TextureBuffer(LandscapeTexture)
	For Y = 0 To LandscapeSize - 1
		For X = 0 To LandscapeSize - 1
			Height# = TerrainHeight#(Landscape, X, Y)
			If Height# > SandThreshold# Then
				WritePixel X, Y, $FF00FF00
			Else
				WritePixel X, Y, $FFFFFF00
			End If
			If Height# > BushesThreshold# Then
				Quantity# = 1.0 * (Height# - BushesThreshold#) / (MaxBushesThreshold# - BushesThreshold#)
				If Quantity# > 1.0 Then Quantity# = 1.0
				BushQuantityMap#(Floor(X / GrassGridCellSize#), Floor(Y / GrassGridCellSize#)) = Quantity# * BushesDensityLevelsQuantity
			End If
		Next
	Next
End Function

Function PaintTextures()
	ScaleTexture LandscapeTexture, LandscapeSize, -LandscapeSize
	TerrainShading Landscape, True

	ScaleTexture LandscapeDitheringTexture, DitheringTextureScale, DitheringTextureScale
	SetBuffer TextureBuffer(LandscapeDitheringTexture)
	For Y = 0 To DitheringTextureSize
		For X = 0 To DitheringTextureSize
			WritePixel X, Y, (Rand(96,160) * $010101) Or $FF000000
		Next
	Next

	EntityTexture Landscape, LandscapeDitheringTexture
	EntityTexture Landscape, LandscapeTexture, 0, 1
	TextureBlend LandscapeTexture, 2
End Function

Function CreateBushes()
	;SetBuffer BackBuffer()
	SetBuffer FrontBuffer()
	Text 0, 20, "Painting textures..."

	SetBuffer TextureBuffer(Grass)
	For Y = 0 To BushTextureSize * BushTypesQuantity - 1
		For X = 0 To BushTextureSize * BushModelsQuantity - 1
			WritePixel X, Y, 256 * GrassBackground
		Next
	Next

	For n1 = 0 To BushTypesQuantity - 1
		For n2 = 0 To BushModelsQuantity - 1
			
			m = CreateMesh()
			s = CreateSurface(m)
			If n1 = 0 Then
				For nn = 1 To 100 + n2 * 100
					Radius# = Rnd(BushTextureSize / 2, BushTextureSize)
					X = BushTextureSize * (Rnd(0,1) ^ 2 * (Rand(0, 1) * 2 - 1) + 1) * 0.5
					Repeat
						Angle# = Rnd(70, 110)
						X2 = Cos(Angle#) * Radius# + X
						Y2 = BushTextureSize - 1 - Sin(Angle#) * Radius# + n2 * BushTextureSize
					Until X2 >=0 And X2 < BushTextureSize
					For DeltaX = -3 To 3
						Color 0, GrassColor + DeltaX * GrassDColor, 0
						Line X + DeltaX, (n2 + 1) * BushTextureSize - 1, X2, Y2
					Next
				Next
				For nn= 0 To 7
					Angle# = nn * 45
					;CreateQuad s, Cos(Angle# - 45), Sin(Angle# - 45), Cos(Angle# + 45), Sin(Angle# + 45), Cos(Angle#) * 0.75, Sin(Angle#) * 0.75
					CreateQuad s, Cos(Angle#) * 0.5, Sin(Angle#) * 0.5, -Cos(Angle#) * 0.5, -Sin(Angle#) * 0.5, n1, n2, Cos(Angle# + 90), Sin(Angle# + 90)
				Next
			Else
				For nn = 1 To 150 + n2 * 150
					X = Rnd(BushTextureSize * 2 / 5, BushTextureSize * 3 / 5) + BushTextureSize
					Angle# = Rnd(10, 170)
					Radius# = Rnd(0, 1) * (1 - Abs(angle - 90) / 133) *  BushTextureSize
					X2 = Cos(Angle#) * Radius# + BushTextureSize / 2 + BushTextureSize
					Y2 = (n2 + 1) * BushTextureSize - 1 - Sin(Angle#) * Radius# 
					For DeltaX = -3 To 3
						Color 0, GrassColor + DeltaX * GrassDColor, 0
						Line X + DeltaX, (n2 + 1) * BushTextureSize - 1, X2, Y2
					Next
				Next
				For nn = 0 To 3
					Angle# = nn * 45
					xx# = Cos(Angle#)
					yy# = Sin(Angle#)
					CreateQuad s, xx#, yy#, -xx#, -yy#, n1, n2
				Next
			End If
			BushModel(n1, n2) = m
			HideEntity m
		Next
	Next

	SetBuffer FrontBuffer()
	Color 255, 255, 255
	Text 0, 30, "Generating grass squares (it might take some more time)..."

	If GrassMethod = MethodHide Then
		For Z = 0 To GrassGridSize - 1
			For X = 0 To GrassGridSize - 1
				m = CreateMesh()
				For n3 = 1 To BushesDensityLevelsQuantity * BushesQuantityMultiplier
					Repeat
						DX# = Rnd(-MaxGrassSpreadingRadius#, MaxGrassSpreadingRadius#)
						DZ# = Rnd(-MaxGrassSpreadingRadius#, MaxGrassSpreadingRadius#)
						If  Sqr(DX# * DX# + DZ# * DZ#) <= MaxGrassSpreadingRadius# Then

							LX# = (DX# + X) * GrassGridCellSize#
							LZ# = (DZ# + Z) * GrassGridCellSize# 

							H# = TerrainY(Landscape, LX#, 0, LZ#)
							Height# = H# / LandscapeHeight#
							If Height# > BushesThreshold# Then
								Quantity# = 1.0 * (Height# - BushesThreshold#) / (MaxBushesThreshold# - BushesThreshold#)
								If Rnd(1) < Quantity# Then
									m2 = CopyMesh(BushModel(Rand(0, BushTypesQuantity - 1), Rand(0, BushModelsQuantity - 1)))
									SXZ# = Rnd(BushModelScaleMin#, BushModelScaleMax#)
									SY# = Rnd(BushModelScaleMin#, BushModelScaleMax#)
									DY1# = TerrainY(Landscape, LX# + 1.0, 0, LZ#) - H#
									DY2# = TerrainY(Landscape, LX#, 0, LZ# + 1.0) - H#
									AlignToVector m2, -DY1#, 1.0, -DY2#, 2
									RotateMesh m2, 0, Rnd(0,359), 0
									ScaleMesh m2, SXZ#, SY#, SXZ#
									s = GetSurface(m2, 1)
									For n = 0 To CountVertices(s) - 1
										VertexNormal s, n, 0, 1, 0
									Next
									RotateMesh m2, EntityPitch(m2), EntityYaw(m2) , EntityRoll(m2)
									PositionMesh m2, LX#, H#, LZ#
									AddMesh m2, m
									FreeEntity m2
								End If
							End If
							Exit
						End If
					Forever
				Next
				BushMap(X, Z) = m
				EntityFX m, 16
				EntityTexture m, Grass
				HideEntity m
				EntityAlpha m, 0.0
			Next
		Next
	Else
		For n1 = 0 To GrassSquareModelsQuantity - 1
			For n2 = 0 To BushesDensityLevelsQuantity - 1
				m = CreateMesh()
				For n3 = 1 To (n2 + 1) * BushesQuantityMultiplier
					m2 = CopyMesh(BushModel(Rand(0, BushTypesQuantity - 1), Rand(0, BushModelsQuantity - 1)))
					DX# = Rnd(-0.5, 0.5): DZ# =Rnd(-0.5, 0.5)
					SXZ# = Rnd(BushModelScaleMin#, BushModelScaleMax#) / GrassGridCellSize#
					SY# = Rnd(BushModelScaleMin#, BushModelScaleMax#) / GrassGridCellSize#
					RotateMesh m2, 0, Rnd(0,359), 0
					ScaleMesh m2, SXZ#, SY#, SXZ#
					PositionMesh m2, DX#, 0, DZ#
					s = GetSurface(m2, 1)
					For n = 0 To CountVertices(s) - 1
						VertexNormal s, n, 0, 1, 0
					Next
					AddMesh m2, m
					FreeEntity m2
				Next
				ScaleMesh m, GrassGridCellSize#, GrassGridCellSize#, GrassGridCellSize#
				EntityFX m, 16
				EntityTexture m, Grass
				HideEntity m
				GrassSquareModel(n1, n2) = m
			Next
		Next
	End If

	For n1 = 0 To BushTypesQuantity - 1
		For n2 = 0 To BushModelsQuantity - 1
			FreeEntity BushModel(n1, n2)
		Next
	Next
End Function

Function CreateQuad(Surface, X1#, Y1#, X2#, Y2#, XTex#, YTex#, DX# = 0, DY# = 0)
	XTex# = XTex# * BushTextureXTexSize#
	YTex# = YTex# * BushTextureYTexSize#
	v1 = AddVertex(Surface, X1#, 0, Y1#, XTex#, YTex# + BushTextureYTexSize#)
	v2 = AddVertex(Surface, X1# + DX#, 1, Y1# + DY#, XTex#, YTex#)
	v3 = AddVertex(Surface, X2# + DX#, 1, Y2# + DY#, XTex# + BushTextureYTexSize#, YTex#)
	v4 = AddVertex(Surface, X2#, 0, Y2#, XTex# + BushTextureYTexSize#, YTex# + BushTextureYTexSize#)
	AddTriangle Surface, v1, v2, v3
	AddTriangle Surface, v3, v4, v1
End Function

Function TryToAddSquare(X, Z)
	S.ActiveSquare = New ActiveSquare
	S\X = X
	S\Z = Z
	S\JustAdded = True
End Function

Function ExpandSquare(S.ActiveSquare)
	If S\X > 0 Then TryToAddSquare S\X - 1, S\Z
	If S\X < GrassGridSize - 1 Then TryToAddSquare S\X + 1, S\Z
	If S\Z > 0 Then TryToAddSquare S\X, S\Z - 1
	If S\Z < GrassGridSize - 1 Then TryToAddSquare S\X, S\Z + 1
End Function

Function CountNeighbors(S.ActiveSquare, NeighborType)
	If S\X > 0 Then If (ServiceMap(S\X - 1, S\Z) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	If S\X < GrassGridSize - 1 Then If (ServiceMap(S\X + 1, S\Z) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	If S\Z > 0 Then If (ServiceMap(S\X, S\Z - 1) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	If S\Z < GrassGridSize - 1 Then If (ServiceMap(S\X, S\Z + 1) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	Return SquaresQuantity
End Function
Лайт версия - только пре-генерация.

SeedRnd MilliSecs()

Const LandscapeSize = 256
Const DitheringTextureSize = 512
Const DitheringTextureScale = 4
Const LandscapeSizeMask = LandscapeSize - 1
Const LandscapeHeight# = 32

Const GrassColor = 100
Const GrassDColor = 20
Const GrassBackground = 100
Const MaxGrassSpreadingRadius# = 0.72

Const BushesThreshold# = 0.28
Const MaxBushesThreshold# = 0.34
Const SandThreshold# = 0.3
Const HillsMinRadius = 16
Const HillsMaxRadius = 64
Const HillsMinHeight# = 0.2
Const HillsMaxHeight# = 1.0
Const HillsQuantity# = 100

Const BushTypesQuantity = 2
Const BushModelsQuantity = 2
Const BushTextureSize = 256

Const BushModelScaleMin# = 0.3
Const BushModelScaleMax# = 0.6

Const PlayerHeight# = 1.5
Const PlayerSpeedPerSecond# = 10.0
Const PlayerTurnPerSecond# = 180.0

Const FadingTimeInSeconds# = 1.0
Const MaxAlpha# = 1.0



;Small grass quadrants - smooth, but slow grass rendering
Const GrassGridCellSize# = 2.0
Const BushesQuantityPerSquare = 12
Const GrassRadiusInSquares# = 8


;Largel grass quadrants - jerky, but fast grass rendering
;Const GrassGridCellSize# = 8.0
;Const BushesQuantityPerSquare = 192
;Const GrassRadiusInSquares# = 2


Const GrassGridSize = LandscapeSize / GrassGridCellSize#
Const BushTextureXTexSize# = 1.0 / BushTypesQuantity
Const BushTextureYTexSize# = 1.0 / BushModelsQuantity
Const GrassRadius# = GrassRadiusInSquares# * GrassGridCellSize#

Graphics3D 800, 600
Camera = CreateCamera()
ScaleEntity camera, 0.3, 0.3, 0.3
PositionEntity Camera, LandscapeSize / 2, 100, LandscapeSize / 2
;RotateEntity Camera, 45, 0, 0
RotateEntity CreateLight(), 45, 45, 0


Type ActiveSquare
	Field X, Z, JustAdded
End Type

Type FadingBush
	Field Alpha#, FadingMode, X, Z
End Type

Dim ServiceMap(LandscapeSize, LandscapeSize)
Const VisibleActiveSquare = %11
Const InvisibleActiveSquare = %10
Const VisibleSquare = %01
Const InvisibleSquare = %00
Const Visibility = %01
Const Activity = %10

Dim BushModel(BushTypesQuantity - 1, BushModelsQuantity - 1)
Dim BushQuantityMap#(GrassGridSize - 1, GrassGridSize - 1)
Dim BushMap(GrassGridSize - 1, GrassGridSize - 1)
Dim BushFader.FadingBush(GrassGridSize - 1, GrassGridSize - 1)

Global Landscape = CreateTerrain(LandscapeSize)
Global LandscapeTexture = CreateTexture(LandscapeSize, LandscapeSize, 15)
Global LandscapeDitheringTexture = CreateTexture(DitheringTextureSize, DitheringTextureSize, 15)
Global Grass = CreateTexture(BushTextureSize * BushTypesQuantity, BushTextureSize * BushModelsQuantity, 13)
ScaleEntity Landscape, 1, LandscapeHeight#, 1

CreateLandscape

CreateBushes

PaintTextures

TryToAddSquare EntityX(Camera) / GrassGridCellSize#, EntityZ(Camera) / GrassGridCellSize#

Const FadingIn = 1, FadingOut = 2

Repeat
	MoveEntity Camera, 0, 0, PrevFrameRenderingTimeInSeconds# * PlayerSpeedPerSecond# * (KeyDown(200) - KeyDown(208))
	TurnEntity Camera, 0, PrevFrameRenderingTimeInSeconds# * PlayerTurnPerSecond# * (KeyDown(203) - KeyDown(205)), 0

	FrameBeginningTime = MilliSecs()

	PlayerX# = EntityX(Camera)
	PlayerZ# = EntityZ(Camera)
	PositionEntity Camera, PlayerX#, TerrainY#(Landscape, PlayerX#, 0, PlayerZ#) + PlayerHeight#, PlayerZ#

	SetBuffer TextureBuffer(LandscapeTexture)

	qua = 0
	For S.ActiveSquare=Each ActiveSquare
		tmp = ServiceMap(S\X, S\Z)
		If (ServiceMap(S\X, S\Z) And Activity) = Activity And S\JustAdded Then
		 	Delete S
		Else
			S\JustAdded = False
			Dist# = EntityDistance(BushMap(S\X, S\Z), Camera)
			;Stop
			If Dist# > GrassRadius# Then
				If (ServiceMap(S\X, S\Z) And Visibility) = VisibleSquare Then
					ExpandSquare S
					If Paint Then WritePixel S\X * GrassGridCellSize#, S\Z * GrassGridCellSize#, $FF00FFFF
					If BushMap(S\X, S\Z) Or GrassMethod = MethodHide Then
						If BushFader(S\X, S\Z) <> Null Then
							FB.FadingBush = BushFader(S\X, S\Z)
						Else
							FB.FadingBush = New FadingBush
							FB\X = S\X
							FB\Z = S\Z
							FB\Alpha# = MaxAlpha#
							BushFader(S\X, S\Z) = FB
						End If
						FB\FadingMode = FadingOut
					End If
					ServiceMap(S\X, S\Z) = InvisibleActiveSquare
				Else
					If CountNeighbors(S, VisibleSquare) = 0 Then
						ServiceMap(S\X, S\Z) = InvisibleSquare
						Delete S
					Else
						ServiceMap(S\X, S\Z) = InvisibleActiveSquare
					End If
				End If
			Else
				If (ServiceMap(S\X, S\Z) And Visibility) = InvisibleSquare Then
					ExpandSquare S
					If Paint Then WritePixel S\X * GrassGridCellSize#, S\Z * GrassGridCellSize#, $FFFF0000
					ServiceMap(S\X, S\Z) = VisibleActiveSquare
					S\JustAdded = False
					ShowEntity BushMap(S\X, S\Z)
					If BushFader(S\X, S\Z) <> Null Then
						FB.FadingBush = BushFader(S\X, S\Z)
					Else
						FB.FadingBush = New FadingBush
						FB\X = S\X
						FB\Z = S\Z
						FB\Alpha# = 0.0
						BushFader(S\X, S\Z) = FB
					End If
					FB\FadingMode = FadingIn
				Else
					If CountNeighbors(S, InvisibleSquare) = 0 Then
						ServiceMap(S\X, S\Z) = VisibleSquare
						Delete S
					Else
						ServiceMap(S\X, S\Z) = VisibleActiveSquare
					End If
				End If
			End If
		End If
	Next

	DFading# = PrevFrameRenderingTimeInSeconds# / FadingTimeInSeconds#
	For FB.FadingBush = Each FadingBush
		A# = FB\Alpha#
		If FB\FadingMode = FadingIn Then
			A# = A# + DFading#
			If A# > MaxAlpha# Then A# = MaxAlpha#
			FB\Alpha# = A#
			EntityAlpha BushMap(FB\X, FB\Z), A#
			If A# = MaxAlpha# Then Delete FB
		Else
			A# = A# - DFading#
			If A# < 0.0 Then A# = 0.0
			FB\Alpha# = A#
			EntityAlpha BushMap(FB\X, FB\Z), A#
			If A# = 0.0 Then
				HideEntity BushMap(FB\X, FB\Z)
				BushFader(FB\X, FB\Z) = Null
				Delete FB
			End If
		End If
	Next

	For S.ActiveSquare=Each ActiveSquare
		qua = qua + 1
	Next

	SetBuffer BackBuffer()
	
	RenderWorld

	;Stop

	If FPSCounterResetTime <= MilliSecs() Then
		FPSCounterResetTime = MilliSecs() + 1000
		FPS = FPSCounter
		FPSCounter = 0
	Else
		FPSCounter = FPSCounter + 1
	End If
	Text 0, 0, "Frames / sec:" + FPS + ", activesquares: " + qua

	Flip

	PrevFrameRenderingTimeInSeconds# = 0.001 * (MilliSecs() - FrameBeginningTime)
Until KeyHit(1)

For X = 0 To GrassGridSize - 1
	For Y = 0 To GrassGridSize - 1
		If BushMap(X, Y) Then FreeEntity BushMap(X, Y)
	Next
Next

FreeEntity Landscape
FreeTexture LandscapeTexture
FreeTexture LandscapeDitheringTexture

Function CreateLandscape()
	SetBuffer FrontBuffer()
	Text 0, 0, "Generating landscape..."
	For n = 1 To HillsQuantity
		HillRadius = Rnd(HillsMinRadius, HillsMaxRadius)
		HillX = Rand(0, LandscapeSize)
		HillY = Rand(0, LandscapeSize)
		HillHeight# = Rnd(HillsMinHeight#, HillsMaxHeight#)

		If -HillRadius < -HillX Then DXFrom = -HillX Else DXFrom = -HillRadius
		If HillRadius > LandscapeSize - HillX Then DXTo = LandscapeSize - HillX - 1 Else DXTo = HillRadius
		If -HillRadius < -HillY Then DYFrom = -HillY Else DYFrom = -HillRadius
		If HillRadius > LandscapeSize - HillY Then DYTo = LandscapeSize - HillY - 1 Else DYTo = HillRadius

		For DY = DYFrom To DYTo
			For DX = DXFrom To DXTo
				X = HillX + DX
				Y = HillY + DY
				K# = Sqr(DX * DX + DY * DY) / HillRadius
				If K# > 1.0 Then K# = 1.0
				Height# = 0.5 * (1.0 + Cos(180.0 * K#)) * HillHeight# * HillRadius / 64
				If Height# > TerrainHeight#(Landscape, X, Y) Then ModifyTerrain Landscape, X, Y, Height#
			Next
		Next
	Next

	SetBuffer FrontBuffer()
	Text 0, 10, "Painting landscape..."
	SetBuffer TextureBuffer(LandscapeTexture)
	For Y = 0 To LandscapeSize - 1
		For X = 0 To LandscapeSize - 1
			If TerrainHeight#(Landscape, X, Y) > SandThreshold# Then
				WritePixel X, Y, $FF00FF00
			Else
				WritePixel X, Y, $FFFFFF00
			End If
		Next
	Next
End Function

Function PaintTextures()
	ScaleTexture LandscapeTexture, LandscapeSize, -LandscapeSize
	TerrainShading Landscape, True

	ScaleTexture LandscapeDitheringTexture, DitheringTextureScale, DitheringTextureScale
	SetBuffer TextureBuffer(LandscapeDitheringTexture)
	For Y = 0 To DitheringTextureSize
		For X = 0 To DitheringTextureSize
			WritePixel X, Y, (Rand(96,160) * $010101) Or $FF000000
		Next
	Next

	EntityTexture Landscape, LandscapeDitheringTexture
	EntityTexture Landscape, LandscapeTexture, 0, 1
	TextureBlend LandscapeTexture, 2
End Function

Function CreateBushes()
	;SetBuffer BackBuffer()
	SetBuffer FrontBuffer()
	Text 0, 20, "Painting textures..."

	SetBuffer TextureBuffer(Grass)
	For Y = 0 To BushTextureSize * BushTypesQuantity - 1
		For X = 0 To BushTextureSize * BushModelsQuantity - 1
			WritePixel X, Y, 256 * GrassBackground
		Next
	Next

	For n1 = 0 To BushTypesQuantity - 1
		For n2 = 0 To BushModelsQuantity - 1
			
			m = CreateMesh()
			s = CreateSurface(m)
			If n1 = 0 Then
				For nn = 1 To 100 + n2 * 100
					Radius# = Rnd(BushTextureSize / 2, BushTextureSize)
					X = BushTextureSize * (Rnd(0,1) ^ 2 * (Rand(0, 1) * 2 - 1) + 1) * 0.5
					Repeat
						Angle# = Rnd(70, 110)
						X2 = Cos(Angle#) * Radius# + X
						Y2 = BushTextureSize - 1 - Sin(Angle#) * Radius# + n2 * BushTextureSize
					Until X2 >=0 And X2 < BushTextureSize
					For DeltaX = -3 To 3
						Color 0, GrassColor + DeltaX * GrassDColor, 0
						Line X + DeltaX, (n2 + 1) * BushTextureSize - 1, X2, Y2
					Next
				Next
				For nn= 0 To 7
					Angle# = nn * 45
					;CreateQuad s, Cos(Angle# - 45), Sin(Angle# - 45), Cos(Angle# + 45), Sin(Angle# + 45), Cos(Angle#) * 0.75, Sin(Angle#) * 0.75
					CreateQuad s, Cos(Angle#) * 0.5, Sin(Angle#) * 0.5, -Cos(Angle#) * 0.5, -Sin(Angle#) * 0.5, n1, n2, Cos(Angle# + 90), Sin(Angle# + 90)
				Next
			Else
				For nn = 1 To 150 + n2 * 150
					X = Rnd(BushTextureSize * 2 / 5, BushTextureSize * 3 / 5) + BushTextureSize
					Angle# = Rnd(10, 170)
					Radius# = Rnd(0, 1) * (1 - Abs(angle - 90) / 133) *  BushTextureSize
					X2 = Cos(Angle#) * Radius# + BushTextureSize / 2 + BushTextureSize
					Y2 = (n2 + 1) * BushTextureSize - 1 - Sin(Angle#) * Radius# 
					For DeltaX = -3 To 3
						Color 0, GrassColor + DeltaX * GrassDColor, 0
						Line X + DeltaX, (n2 + 1) * BushTextureSize - 1, X2, Y2
					Next
				Next
				For nn = 0 To 3
					Angle# = nn * 45
					xx# = Cos(Angle#)
					yy# = Sin(Angle#)
					CreateQuad s, xx#, yy#, -xx#, -yy#, n1, n2
				Next
			End If
			BushModel(n1, n2) = m
			HideEntity m
		Next
	Next

	SetBuffer FrontBuffer()
	Color 255, 255, 255
	Text 0, 30, "Generating grass squares (it might take some more time)..."

	For Z = 0 To GrassGridSize - 1
		For X = 0 To GrassGridSize - 1
			m = CreateMesh()
			EX# = X * GrassGridCellSize#
			EZ# = Z * GrassGridCellSize#
			EH# = TerrainY(Landscape, EX#, 0, EZ#)
			For n3 = 1 To BushesQuantityPerSquare
				Repeat
					DX# = Rnd(-MaxGrassSpreadingRadius#, MaxGrassSpreadingRadius#)
					DZ# = Rnd(-MaxGrassSpreadingRadius#, MaxGrassSpreadingRadius#)
					If  Sqr(DX# * DX# + DZ# * DZ#) <= MaxGrassSpreadingRadius# Then
						LX# = DX# * GrassGridCellSize# + EX#
						LZ# = DZ# * GrassGridCellSize# + EZ#
						LH# = TerrainY(Landscape, LX#, 0, LZ#)
						DH# = LH# - EH#

						Height# = LH# / LandscapeHeight#
						If Height# > BushesThreshold# Then
							Quantity# = 1.0 * (Height# - BushesThreshold#) / (MaxBushesThreshold# - BushesThreshold#)
							If Rnd(1) < Quantity# Then
								m2 = CopyMesh(BushModel(Rand(0, BushTypesQuantity - 1), Rand(0, BushModelsQuantity - 1)))
								SXZ# = Rnd(BushModelScaleMin#, BushModelScaleMax#)
								SY# = Rnd(BushModelScaleMin#, BushModelScaleMax#)
								DY1# = TerrainY(Landscape, LX# + 1.0, 0, LZ#) - LH#
								DY2# = TerrainY(Landscape, LX#, 0, LZ# + 1.0) - LH#
								AlignToVector m2, -DY1#, 1.0, -DY2#, 2
								RotateMesh m2, 0, Rnd(0,359), 0
								ScaleMesh m2, SXZ#, SY#, SXZ#
								s = GetSurface(m2, 1)
								For n = 0 To CountVertices(s) - 1
									VertexNormal s, n, 0, 1, 0
								Next
								RotateMesh m2, EntityPitch(m2), EntityYaw(m2) , EntityRoll(m2)
								PositionMesh m2, DX# * GrassGridCellSize#, DH#, DZ# * GrassGridCellSize#
								AddMesh m2, m
								FreeEntity m2
							End If
						End If
						Exit
					End If
				Forever
			Next
			BushMap(X, Z) = m
			PositionEntity m, EX#, EH#, EZ#
			EntityFX m, 16
			EntityTexture m, Grass
			HideEntity m
			EntityAlpha m, 0.0
		Next
	Next

	For n1 = 0 To BushTypesQuantity - 1
		For n2 = 0 To BushModelsQuantity - 1
			FreeEntity BushModel(n1, n2)
		Next
	Next
End Function

Function CreateQuad(Surface, X1#, Y1#, X2#, Y2#, XTex#, YTex#, DX# = 0, DY# = 0)
	XTex# = XTex# * BushTextureXTexSize#
	YTex# = YTex# * BushTextureYTexSize#
	v1 = AddVertex(Surface, X1#, 0, Y1#, XTex#, YTex# + BushTextureYTexSize#)
	v2 = AddVertex(Surface, X1# + DX#, 1, Y1# + DY#, XTex#, YTex#)
	v3 = AddVertex(Surface, X2# + DX#, 1, Y2# + DY#, XTex# + BushTextureYTexSize#, YTex#)
	v4 = AddVertex(Surface, X2#, 0, Y2#, XTex# + BushTextureYTexSize#, YTex# + BushTextureYTexSize#)
	AddTriangle Surface, v1, v2, v3
	AddTriangle Surface, v3, v4, v1
End Function

Function TryToAddSquare(X, Z)
	S.ActiveSquare = New ActiveSquare
	S\X = X
	S\Z = Z
	S\JustAdded = True
End Function

Function ExpandSquare(S.ActiveSquare)
	If S\X > 0 Then TryToAddSquare S\X - 1, S\Z
	If S\X < GrassGridSize - 1 Then TryToAddSquare S\X + 1, S\Z
	If S\Z > 0 Then TryToAddSquare S\X, S\Z - 1
	If S\Z < GrassGridSize - 1 Then TryToAddSquare S\X, S\Z + 1
End Function

Function CountNeighbors(S.ActiveSquare, NeighborType)
	If S\X > 0 Then If (ServiceMap(S\X - 1, S\Z) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	If S\X < GrassGridSize - 1 Then If (ServiceMap(S\X + 1, S\Z) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	If S\Z > 0 Then If (ServiceMap(S\X, S\Z - 1) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	If S\Z < GrassGridSize - 1 Then If (ServiceMap(S\X, S\Z + 1) And Visibility) = NeighborType Then SquaresQuantity = SquaresQuantity + 1
	Return SquaresQuantity
End Function
Пользуйтесь свободно, public domain.
(Offline)
 
Ответить с цитированием
Старый 10.06.2007, 09:23   #2
johnk
Легенда
 
Регистрация: 01.10.2006
Сообщений: 3,705
Написано 296 полезных сообщений
(для 568 пользователей)
Re: Реализовал много травы

Мне понравилось
(Offline)
 
Ответить с цитированием
Старый 10.06.2007, 12:12   #3
ЛысыЙ_Чук-Иванчук
Дэвелопер
 
Регистрация: 19.03.2006
Сообщений: 1,241
Написано 10 полезных сообщений
(для 17 пользователей)
Re: Реализовал много травы

Неплохо, даже понравилось...
(Offline)
 
Ответить с цитированием
Старый 10.06.2007, 15:01   #4
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
Re: Реализовал много травы

с учетом наложения на неровную поверхность ландшафта, все начинает выглядеть крайне коряво - трава висит в воздухе / тонет под землей и отчетливо видна "травяная плоскость".
Можно забить в массив - карту травы данные о конфигурации пейзажа в точке, и размещать там типовые травяные полянки: густые, редкие, изогнутые под горы и впадины и т.п. Для того, чтоб трава не очень "висела", можно сделать кусты более вытянутыми по вертикали, так, чтоб в нормальном состоянии трава была частично погружена в землю.
Однако идея динамического размещения травы всё же вызывавет у меня заряд скепсиса. Более высокую производитльность она покажет только на картах, где общее количество травы крайне велико и несоизмеримо превосходит видимую травяную плоскость. Представить себе производительную реализацию такой огромной карты и всех прочих ёё элементов на Блице я не решаюсь.

1) При большом размере квадратов возникает эффект "травяных пашен" ... Думаю, можно поэкспериментировать с изменением формы и частичным взаимным перекрыванием участков, добившись лучшего результата.
Согласен. Взаимное перекрытие- это разумная идея. В теории несложно представить себе взаимно смещенные на полгабарита кластеры-пашни, у которых кусты не пересекаются, потому что растут, к примеру, соответственно по "чётным и нечетным координатам". На производительность никак не повлияет.

2) Какой оптимальный размер для квадратов?
ИМХО- максимально большой из красивых.))

3) Каким установить время проявления новых участков? Небольшим - трава будет резко появляться, малым - кол-во видимых участков увеличится, что отрицательно скажется на FPS.
ИМХО- при скорости фейдинга, заведомо большей, чем скорость перехода игрока с кластера на кластер, т.е. в ситуации, максимально приближенной к практике- это не принципиально.

4) Как быть с прозрачностью?
Альфаканал фтопку.

В плане кода.
0. Думаю, "Flip 0" будет несколько полезней для подсчёта ФПС.
1.[blitz]DX# = S\X - PlayerX# / GrassGridCellSize#
DZ# = S\Z - PlayerZ# / GrassGridCellSize#
Distance# = Sqr(DX# * DX# + DZ# * DZ#)[/blitz]
Эмпирика показывает, что следует избегать столь тяжелых математических конструкций. Так, EntityDistance будет выполняться на порядок быстрее.

2. Мне не вполне понятна этимология генезиса институции типа ActiveSquare в ситуации с предварительно загенереной картой растительности. Работа напрямую с массивом кластеров травы будет проходить несколько быстрее, кроме того, код станет явно проще.

Примитивно говоря, можно так, как приведено ниже. Нужен доп. массив- карта видимости кластеров, и скорость фейдинга травы по понятным причинам должна быть достаточно велика ( я увеличивал до 0.5).
	MapX=PlayerX/GrassGridCellSize#
	MapZ=PlayerZ/GrassGridCellSize#
	AnalyzedDis=GrassRadius+FadingTimeInSeconds#*PlayerSpeedPerSecond#+2
	For x=MapX-AnalyzedDis To MapX+AnalyzedDis
	For z=MapZ-AnalyzedDis To MapZ+AnalyzedDis
	If x>=0 And x<GrassGridSize And z>=0 And z<GrassGridSize Then
;!---такой метод определения дистанции до точки- непроизводителен
;!---и уступает ЁнтитиДистансу в несколько раз
		If Abs(x-MapX)<GrassRadius And Abs(z-MapZ)<GrassRadius Then
			If BushMapVisible#(x,z)<1 Then
			If BushMapVisible#(x,z)=0 Then ShowEntity BushMap(x,z)
				BushMapVisible#(x,z)=BushMapVisible#(x,z)+PrevFrameRenderingTimeInSeconds# / FadingTimeInSeconds#
				EntityAlpha BushMap(x,z),BushMapVisible#(x,z)
			EndIf
		Else
			If BushMapVisible#(x,z)>0 Then
				BushMapVisible#(x,z)=BushMapVisible#(x,z)-PrevFrameRenderingTimeInSeconds# / FadingTimeInSeconds#
				EntityAlpha BushMap(x,z),BushMapVisible#(x,z)
				If BushMapVisible#(x,z)<=0 Then HideEntity BushMap(x,z)
			EndIf
		EndIf
	EndIf
	Next
	Next
P.S. Сори, при вставке кода почему-то гибнут отступы табуляции.


__________
Добавлено:

Изменил теги, пропатчил код.
(Offline)
 
Ответить с цитированием
Старый 10.06.2007, 18:32   #5
Matt Merkulov
Модератор
 
Аватар для Matt Merkulov
 
Регистрация: 23.10.2005
Сообщений: 219
Написано 62 полезных сообщений
(для 247 пользователей)
Re: Реализовал много травы

Насчет Flip 0, EntityDistance: да, верно. Про последнее я уже и забыл...

Мне не вполне понятна этимология генезиса институции типа ActiveSquare в ситуации с предварительно загенереной картой растительности.
Это оправдано при маленьких размерах травяных квадратов и соотв. больших размерах травяной области. Тогда проверяются только квадраты на границе травы. Кстати, Ожегов рулит, его тоже иногда стоит юзать .

P.S. Сори, при вставке кода почему-то гибнут отступы табуляции.
А какими ты тегами код обрамляешь?
(Offline)
 
Ответить с цитированием
Старый 10.06.2007, 20:34   #6
Diplomat
Дэвелопер
 
Регистрация: 07.09.2005
Сообщений: 1,519
Написано 66 полезных сообщений
(для 164 пользователей)
Re: Реализовал много травы

Это оправдано при маленьких размерах травяных квадратов и соотв. больших размерах травяной области. Тогда проверяются только квадраты на границе травы.
А, всё, понял. Точно, всё так, я просто не чётко разобрался в коде. Ну что-ж, тогда - еще один отдельный респект за идею!
...
Но реализация идеи имеет два недостатка:
0. В таком виде она фактически не может дать прирост скорости. Так метод, основанный на моем "решении", приведенном выше, работает в два-три раза быстрее, причём значительное увеличение площади отображаемого участка не слишком меняет картину. Многочисленные операции с типами и математический замер дистанции до точки сильно снижают производительность твоего кода. В то же время мой вложенный цикл и простые операции с двухмерным массивом хоть и осуществляются за бОльшее количество проходов, но выполняется намного быстрее. Увеличь GrassRadius, замерь миллисекунды- и увидишь. Чтоб твой метод по настоящему "полетел"- ему необходима дополнительная оптимизация.
1. В таком виде твой код имеет баг: заметную утечку памяти. Заметь, сколько создаётся активных точке- и сколько удаляется.

А какими ты тегами код обрамляешь?
[blіtz][/blіtz]
Сейчас попробую заменить на штатные [сode][/сode]
_________
Добавлено:
Да, теперь нормально.



Кстати, Ожегов рулит, его тоже иногда стоит юзать
Ага. А еще Даль и Гринченко. Кстати, то была шутка- высказывание в стиле раннего Имерсоналиса. Признаю, острота довольно нелепая и неуместная.
Впрочем, если серьезно- то фраза перегружена, но вполне правильна. Даже "этимология" упоминается вполне к месту. Я готов послушать доказательство обратного, но в другой теме. :p

(Offline)
 
Ответить с цитированием
Старый 14.06.2007, 06:14   #7
Matt Merkulov
Модератор
 
Аватар для Matt Merkulov
 
Регистрация: 23.10.2005
Сообщений: 219
Написано 62 полезных сообщений
(для 247 пользователей)
Re: Реализовал много травы

Устранил утечку активных квадрантов и внедрил EntityDistance в лайт версию. Новые типы создаются только если травяная область "перемещается", если, например, стоять, то будет только проверяться расстояние до активных квадратов в списке. Впрочем, при всех этих ухищрениях если и будет выигрыш в производительности, то незначительный, здесь ты, наверное, прав.

Да я понял, что шутка, просто фраза показалась мне абсурдной. В личке спрошу .
(Offline)
 
Ответить с цитированием
Старый 15.06.2007, 03:54   #8
Matt Merkulov
Модератор
 
Аватар для Matt Merkulov
 
Регистрация: 23.10.2005
Сообщений: 219
Написано 62 полезных сообщений
(для 247 пользователей)
Re: Реализовал много травы

Вот я все не могу понять, почему моя прога жрет столько памяти? На что уходят эти 300MB?
(Offline)
 
Ответить с цитированием
Старый 15.06.2007, 04:13   #9
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Re: Реализовал много травы


кто такой Имерсоналис из 6ого поста?
и как он пошутил?
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 15.06.2007, 10:35   #10
jimon
 
Сообщений: n/a
Re: Реализовал много травы


impersonalis
жжош
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Куча травы. Лучший способ реализации. Данил Blitz3D 99 26.03.2010 18:41
пример травы Illidan 3D-программирование 8 29.12.2009 22:53
Реализую много травы ABTOMAT 3D-программирование 22 03.06.2007 23:17
Рендеринг травы haedim 3D-программирование 16 29.10.2006 17:17
Много чего pax Болтовня 1 27.09.2006 18:07


Часовой пояс GMT +4, время: 04:58.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com