Help with placing 3d object with mouse

Blitz3D Forums/Blitz3D Programming/Help with placing 3d object with mouse

Caton(Posted March) [#1]


How could I fix this?


Midimaster(Posted March) [#2]
fix what?


Caton(Posted March) [#3]
it's not placing at the position of mouse x and y.
it's way off of the screen.


steve_ancell(Posted March) [#4]
MouseX/MouseY (0, 0) starts top-left of the 2D screen, (0, 0) in 3D starts in the centre.


Floyd(Posted March) [#5]
MouseX/Y are screen coordinates while PositionEntity uses 3D world coordinates.

You need some way to find out where the mouse pointer is pointing in the 3D world.
Here is one possible approach.

; Invisible plane is horizontal, all y values are zero.
; Click left mouse button to place a sphere.
; Escape quits.

Graphics3D 1200, 800, 0, 2
SetBuffer BackBuffer()

plane = CreatePlane()

EntityAlpha plane, 0      ; invisible
EntityPickMode plane, 2   ; but pickable

cam = CreateCamera()
PositionEntity cam, 0, +30, -40
AlignToVector  cam, 0, -30, +40, 3
CameraZoom cam, 8

sph = CreateSphere()
ScaleEntity sph, 0.2, 0.2, 0.2
EntityColor sph, 255,255,0

While Not KeyDown(1)
	If MouseHit( 1 )
		mx = MouseX()
		my = MouseY()
		PickedEntity = CameraPick( cam, mx, my ) 
		If PickedEntity = plane
			temp = CopyEntity( sph )
			EntityColor temp, Rand( 100, 250 ), Rand( 100, 250 ), Rand( 100, 250 )
			PositionEntity temp, PickedX(), PickedY(), PickedZ()
		End If
	End If
	RenderWorld
	Text 50, 40, "Mouse x,y:    " + mx + "  " + my
	Text 50, 65, "Entity:       " + PickedEntity
	Text 50, 90, "World x,y,z:  " + PickedX() + "  " + PickedY() + "  " + PickedZ() 
	Flip
Wend



Midimaster(Posted March) [#6]
Dont know, whether there is maybe a special function that works better than my workaround...

I tried out, where are the last visible positions of an object in your current camera range. Results: Objects are visible from x=-10 to +10 and y=+7 to -7.

So I calculate MouseX into ReversProjectedX():
Function AddObject(x#,y#)
	obj.oobject = New oobject

	; your screen range in world coordinates: x= -10 to + 10  and y= 7 to -7
	obj\x#=ReversProjectedX(x)
	obj\y#=ReversProjectedY(y)
	nofobjects=nofobjects+1

	;obj\mesh=LoadMesh("assets\objects\box.b3d")
	obj\mesh=CreateCube()
	
	ScaleEntity obj\mesh,1,1,1
	
	PositionEntity obj\mesh,obj\x#,obj\y#,0
	EntityColor obj\mesh,12,255,15
	EntityType obj\mesh,2
End Function


Function ReversProjectedX#(x#)
	Return (x-400)/40.0
End Function


Function ReversProjectedY#(y#)
	Return -(y-300)/40.0
End Function



Caton(Posted March) [#7]
Thanks


steve_ancell(Posted March) [#8]
If this is to do with offsets then this might help you understand. I you mover the camera to the right and down then (0, 0) with appear to be the top-left of the screen.

My code below is a bit crude but sort of works, I never was one for 3D stuff. You will also need to add in some culling to stop it flying way out of the screen.




gpete(Posted March) [#9]
try this instead..trying to position using MouseX and MouseY needs to translate to 3 dimensions.

Graphics3D 900,700,32,2

SetBuffer BackBuffer()
AntiAlias True
Global nofobjects,cam,tex
;Global up_key = 200, down_key = 208, left_key = 203, right_key = 205
Global W_key = 17, S_key = 31, A_key = 30, D_key = 32

AppTitle("Revised Editor")

; Create texture of size 48,48
tex=CreateTexture(48,48)

; Set buffer - texture buffer
SetBuffer TextureBuffer(tex)

; Clear texture buffer with background color
ClsColor 0,0,0
Cls
For t=1 To 48
For ty=1 To 48
If t Mod 3>0 Then
Color 50,50,50
Plot t,ty
Else
Color 0,100,60
Plot t,ty
End If
Next  ;ty
Next  ;t
; Set buffer - backbuffer
SetBuffer BackBuffer()

;__________________________________
plane=CreatePlane()
EntityTexture plane,tex  ;use generated "tex" image

objj=CreateCube()
PositionEntity objj,0,.7,0
EntityAlpha objj,.5
ScaleEntity objj,.5,.5,.5
cam=CreateCamera(objj)
CameraRange cam,1,200
CameraFogColor cam,20,20,40
CameraFogMode cam,1
CameraFogRange cam,20,60
PositionEntity cam,0,10,-14

SetupLighting()


;------------MAIN----------------------
While Not KeyDown(1)

mx=EntityX#(objj)+0
my=EntityY#(objj)-1
z=EntityZ#(objj)

 
object_key_control_2(objj)

UpdateWorld()

PointEntity cam,objj

If KeyDown(67)
PositionEntity cam,0,4,-15
EndIf

If Not KeyDown(67) Then   
PositionEntity cam,0,10,-14
End If
 


If MouseHit(1) Then
AddObject(mx,my,z)
End If

RenderWorld()

Color 255,255,255
Text 2,20,"X Position:"+mx
Text 2,40,"Y Position:"+my
Text 2,60,"Z Position: "+EntityZ#( objj)
Text 2,80,"Objects:"+nofobjects
Text 2,110,"W A S D to move, Mouse button 1 to place cube, F9-and HOLD,alter camera angle(release F9 to reset)"
Flip
Wend
End
;-------------------------end of main

Function SetupLighting()
;light=CreateLight(2)
AmbientLight 255,255,255
End Function

Function AddObject(x#,y#,z#)
obj.oobject = New oobject
obj\x#=x#
obj\y#=y#
obj\z#=z
nofobjects=nofobjects+1
obj\mesh=CreateCube()
ScaleEntity obj\mesh,.5,1,.5
PositionEntity obj\mesh,obj\x#,obj\y#,obj\z#
EntityColor obj\mesh,Rnd(100,150),Rnd(100,150),Rnd(100,150)
EntityType obj\mesh,2
End Function

Type OObject
Field x#,y#,z#,mesh
End Type

;Function object_key_control( objj )
  ;  If KeyDown( up_key ) = True Then MoveEntity obj, 0, 0, .2
   ; If KeyDown( down_key ) = True Then MoveEntity obj, 0, 0, -.2
   ; If KeyDown( left_key ) = True Then TurnEntity obj, 0, 2, 0
   ; If KeyDown( right_key ) = True Then TurnEntity obj, 0, -2, 0
;End Function

Function object_key_control_2(objj)
    If KeyDown( W_key ) = True Then MoveEntity objj, 0, 0, .2
    If KeyDown( S_key ) = True Then MoveEntity objj, 0, 0, -.2
    If KeyDown( A_key ) = True Then TurnEntity objj, 0, 2, 0
    If KeyDown( D_key ) = True Then TurnEntity objj, 0, -2, 0
End Function




BlitzSupport(Posted March) [#10]
... and this:

2D-to-3D entity positioning (or something)


Caton(Posted March) [#11]
doesn't seem to work when I move the camera to left and add object.



gpete(Posted March) [#12]
so try and figure it out Caton! ;)

A 3d model making program uses a 2D Grid overlay to help in positioning. That is easy to do. If you look at the example I gave you you also need a base level grid to help in positioning. Start by making a flat build surface(a "plane") or a 3D terrain or mesh-use a pattern for it that has a repeating pattern 1 unit across. for a terrain you can easily change the texture to a seamless "ground" one later.


Midimaster(Posted March) [#13]
My workaround was based on a fix camera position. But there is also a chance to calculate it with moving camera: When you move the camera, you have to add/sub the camera position to the calculated object coordinates: