Jump to content

Camera pick does not work on terrain?


Sanctus
 Share

Recommended Posts

Hey

I used this code code to place a entity at the mouse position on the terrain and it doesn't work.

 

Local p:TPick = CameraPick(camera, Vec3(mx, my, 1000), 0, TERRAIN_COL)
If(p <> Null)
PositionEntity(model, Vec3(p.x, p.y, p.z))
EndIf

 

The x and z coordinates are fine but the y (height) is totally wrong. The model stands in air on some places and then stays in the ground on other places.

Anyone experienced this before?

I create the game you play. I create the rulles you will obey.

Link to comment
Share on other sites

I would use EntityPick, since it works fine with all objects. It allows you to make also more reusable code, since not always you have a camera, but always you have an entity.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

EntityPick is useless. I need to pick with the mouse on the screen so I need more than a ray length.

Also if I didn't set up Collisions(TERRAIN_COL,TERRAIN_COL,1) it would work at all so yes I did it.

Way too much atention is put in that useless sandbox when a lot of very important parts of the engine don't work well or are undocumented.

I mean seriously what kind of professional game would use it?

I create the game you play. I create the rulles you will obey.

Link to comment
Share on other sites

hmmm... i am not getting the results you are getting with objects floating in the air, but i am just doing a quick test in a standalone lua script...

require("Scripts/constants/collision_const")
require("Scripts/constants/engine_const")
require("Scripts/math/math")

RegisterAbstractPath("")        
Graphics(800,600)        
fw=CreateFramework()        
scene=LoadScene("Maps/train.sbx") 

controller=CreateController(1.8,0.45,0.25,45,0.9)
controller:SetCollisionType(COLLISION_CHARACTER,0)
controller:SetMass(100)
controller:SetPosition(Vec3(18,1,0))
camerapitch=fw.main.camera.rotation.x
camerayaw=fw.main.camera.rotation.y

local camera = fw.main.camera

HideMouse()
MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)

while KeyHit(KEY_ESCAPE)==0 do        
jump=KeyHit(KEY_SPACE)*6.0        
if controller:IsAirborne()==1 then jump=0 end        
gx=Round(GraphicsWidth()/2)        
gy=Round(GraphicsHeight()/2)        
dx=Curve((MouseX()-gx)/4.0,dx,3.0/AppSpeed())        
dy=Curve((MouseY()-gy)/4.0,dy,3.0/AppSpeed())        
MoveMouse(gx,gy)        
camerapitch=camerapitch+dy        
camerayaw=camerayaw-dx        
camerapitch=math.min(camerapitch,90)        
camerapitch=math.max(camerapitch,-89.99)       
fw.main.camera:SetRotationf(camerapitch,camerayaw,0,1)        
movespeed=4        
movesmoothing=10        
if controller:IsAirborne()==1 then                
	movesmoothing=200        
end 
 	move=Curve( (KeyDown(KEY_W)-KeyDown(KEY_S))*movespeed,move,movesmoothing)        
strafe=Curve( (KeyDown(KEY_D)-KeyDown(KEY_A))*movespeed,strafe,movesmoothing)        

if MouseHit(1)==1 then
	pick=CameraPick(camera,Vec3(GraphicsWidth()/2,GraphicsHeight()/2,1000.0),0,0)
	if pick~=nil then
		if pick.entity:GetClass()==ENTITY_TERRAIN then
			local oildrum = LoadModel("abstract::oildrum.gmf")
			oildrum:SetPosition(Vec3(pick.position.x, pick.position.y, pick.position.z))
		end
	end
end--

controller:Update(camerayaw,move,strafe,jump,400,1)  
fw:Update()        
fw.main.camera:SetPositionf(controller.position.x,controller.position.y+1.8,controller.position.z,1)        
fw:Render()

if pick~=nil then
	SetBlend(1)
	DrawText("Pick Position X: "..pick.position.x,0,60)
	DrawText("Pick Position Y: "..pick.position.y,0,80)
	DrawText("Pick Position Z: "..pick.position.z,0,100)
	SetBlend(0)
end
SetBlend(1)
DrawText("><", GraphicsWidth()/2-8,GraphicsHeight()/2-8)
SetBlend(0)

Flip(0)
end
controller:Free()

ShowMouse()

 

I am however seeing the strange values occurring for the Y value when done on flat terrain at 0 altitude, though seems to work just fine on higher elevation. Perhaps you can use the X & Z values from the pick for the command TerrainElevation to get a more precise Y value. Granted I have tried my method above with CreateCube and a physics model and even with strange Y values, it appears to place the model correctly.

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

using the pick's X&Z for TerrainElevation appears to work just fine

require("Scripts/constants/collision_const")
require("Scripts/constants/engine_const")
require("Scripts/math/math")

RegisterAbstractPath("")        
Graphics(800,600)        
fw=CreateFramework()        
scene=LoadScene("Maps/train.sbx") 

controller=CreateController(1.8,0.45,0.25,45,0.9)
controller:SetCollisionType(COLLISION_CHARACTER,0)
controller:SetMass(100)
controller:SetPosition(Vec3(18,1,0))
camerapitch=fw.main.camera.rotation.x
camerayaw=fw.main.camera.rotation.y

local camera = fw.main.camera

HideMouse()
MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)

while KeyHit(KEY_ESCAPE)==0 do        
jump=KeyHit(KEY_SPACE)*6.0        
if controller:IsAirborne()==1 then jump=0 end        
gx=Round(GraphicsWidth()/2)        
gy=Round(GraphicsHeight()/2)        
dx=Curve((MouseX()-gx)/4.0,dx,3.0/AppSpeed())        
dy=Curve((MouseY()-gy)/4.0,dy,3.0/AppSpeed())        
MoveMouse(gx,gy)        
camerapitch=camerapitch+dy        
camerayaw=camerayaw-dx        
camerapitch=math.min(camerapitch,90)        
camerapitch=math.max(camerapitch,-89.99)       
fw.main.camera:SetRotationf(camerapitch,camerayaw,0,1)        
movespeed=4        
movesmoothing=10        
if controller:IsAirborne()==1 then                
	movesmoothing=200        
end 
 	move=Curve( (KeyDown(KEY_W)-KeyDown(KEY_S))*movespeed,move,movesmoothing)        
strafe=Curve( (KeyDown(KEY_D)-KeyDown(KEY_A))*movespeed,strafe,movesmoothing)        

if MouseHit(1)==1 then
	pick=CameraPick(camera,Vec3(GraphicsWidth()/2,GraphicsHeight()/2,1000.0),0,0)
	if pick~=nil then
		if pick.entity:GetClass()==ENTITY_TERRAIN then
			terrainheight=TerrainElevation(pick.entity, pick.position.x, pick.position.z)
			local oildrum = LoadModel("abstract::oildrum.gmf")
			oildrum:SetPosition(Vec3(pick.position.x, terrainheight, pick.position.z))
		end
	end
end--

controller:Update(camerayaw,move,strafe,jump,400,1)  
fw:Update()        
fw.main.camera:SetPositionf(controller.position.x,controller.position.y+1.8,controller.position.z,1)        
fw:Render()

SetBlend(1)
DrawText("Left-click mousebutton to pick terrain and set model",0,20)
DrawText("><", GraphicsWidth()/2-8,GraphicsHeight()/2-8)
if pick~=nil then
	DrawText("Pick Position X: "..pick.position.x,0,60)
	DrawText("Pick Position Y: "..terrainheight,0,80)
	DrawText("Pick Position Z: "..pick.position.z,0,100)
end
SetBlend(0)

Flip(0)
end
controller:Free()

ShowMouse()

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Thanks for the answer. I will try it a bit later on.

Perhaps those "strange" values are very small values like 3.234234e-24 (don't remember the exact notation)

I create the game you play. I create the rulles you will obey.

Link to comment
Share on other sites

Nope it does not work:

The only thing that get's me a good height is

PositionEntity(model, Vec3(p.x, TerrainElevation(terrain, p.z, p.x), p.z))

where p is the pick returned by CameraPick

But then x and y are a bit screwed up.

Look at tha picture attached. It's as if the x and z are from a flat terrain.

I create the game you play. I create the rulles you will obey.

Link to comment
Share on other sites

It works fine for me in my example using TerrainElevation.

Instead of:

PositionEntity(model, Vec3(p.x, TerrainElevation(terrain, p.z, p.x), p.z))

try this:

PositionEntity(model, Vec3(p.x, TerrainElevation(terrain, p.x, p.z), p.z))

or

PositionEntity(model, Vec3(p.x, TerrainElevation(p.entity, p.x, p.z), p.z))

just depending on how you are filtering out just terrain picks... but either way it looks like you have your p.x & p.z swapped.

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Yes I do have those swapped because otherwise it does not work at all.

I even had to make my rise/lower terrain functions that way because otherwise it doesn't work at all.

Look at this:

Method RiseTerrain(px:Float, py:Float, pz:Float, radius:Float, strength:Float)
For Local x:Int = px - radius / 2 To px + radius / 2
	For Local y:Int = pz - radius / 2 To pz + radius / 2
		Local d:Float = (radius / 2 - Dist2(px, pz, x, y))
		If d < 0
			d = 0
		EndIf
		Local h:Float = d / radius * strength / 1000.0
		If h < 0
			h = 0
		End If
		SetTerrainHeight(terrain, y + Width / 2, x + Height / 2, TerrainHeight(terrain, y + Width / 2, x + Height / 2) + h)
	Next
Next
UpdateTerrainNormals(terrain)
End Method

 

Notice this part "y + Width / 2, x + Height / 2, TerrainHeight(terrain, y + Width / 2, x + Height / 2) + h)". I just had to or it doesn't work right.

Geez there really has to be a tutorial about all the terrain features.

I create the game you play. I create the rulles you will obey.

Link to comment
Share on other sites

well its hard to comment on your implementation in your own editor... I just know it works for the example I gave. If I swap the X & Z in my example, it doesn't work correctly. Perhaps Josh is rotating the terrain to make the terrain's X&Z planes line up with world's planes?

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...