Es gibt irgendwo in den tiefen des Forums (oder des englischen) einen Code, der eine 2d-3d Mausprojektion vornimmt, also berechnet, wohin die 2d maus im 3d raum zeigt.
Vielleicht hilft Dir der weiter (wie gesagt, ist nicht von mir, hab nur keine Ahnung, woher der genau ist)
Code: Alles auswählen
;cheating a bit with this structure - I use it for both 3D points and vectors
Structure vector
x.d
y.d
z.d
EndStructure
Structure mouse
x.l
y.l
v.vector
button.l
over.l
EndStructure
Structure bounded
object.l
centre.vector
radius.d
distance.d
EndStructure
Global height.l, width.l, mousedepth.d, camera.vector, lookat.vector, origin.vector
Global NewList spheres.bounded()
width = 1024
height = 768
mousedepth = -665
;width = 800 ;These numbers seem to work for a
;height = 600 ;800 by 600 screen but the graphic
;mousedepth = -519 ;detail is better at 1024x768
Procedure copy(*a.vector,*b.vector)
*a\x = *b\x
*a\y = *b\y
*a\z = *b\z
EndProcedure
Procedure new(*v.vector,x.d,y.d,z.d)
*v\x = x
*v\y = y
*v\z = z
EndProcedure
Procedure vectorise(*v.vector,*from.vector,*toPoint.vector)
new(*v, *toPoint\x - *from\x,*toPoint\y - *from\y,*toPoint\z - *from\z)
EndProcedure
Procedure equal(*a.vector,*b.vector)
If *a\x <> *b\x:ProcedureReturn 0:EndIf
If *a\y <> *b\y:ProcedureReturn 0:EndIf
If *a\z <> *b\z:ProcedureReturn 0:EndIf
ProcedureReturn 1
EndProcedure
Procedure translate(*v.vector, *t.vector)
*v\x+*t\x
*v\y+*t\y
*v\z+*t\z
EndProcedure
Procedure rotate(*v.vector, *r.vector)
copy(temp.vector,*v) ;rotate x axis
*v\y = temp\y*Cos(-*r\x)-temp\z*Sin(-*r\x)
*v\z = temp\y*Sin(-*r\x)+temp\z*Cos(-*r\x)
copy(temp.vector,*v) ;rotate y axis
*v\z = temp\z*Cos(-*r\y)-temp\x*Sin(-*r\y)
*v\x = temp\z*Sin(-*r\y)+temp\x*Cos(-*r\y)
copy(temp.vector,*v) ;rotate z axis
*v\x = temp\x*Cos(-*r\z)-temp\y*Sin(-*r\z)
*v\y = temp\x*Sin(-*r\z)+temp\y*Cos(-*r\z)
EndProcedure
Procedure.d dot(*a.vector,*b.vector)
ProcedureReturn (*a\x * *b\x)+(*a\y * *b\y)+(*a\z * *b\z)
EndProcedure
Procedure.d angle(*a.vector, *b.vector)
ProcedureReturn ACos(dot(*a,*b)/(Pow(dot(*a,*a),0.5)*Pow(dot(*b,*b),0.5)))
EndProcedure
Procedure map(*v.vector)
a.d:b.d:c.d
vectorise(LA.vector,camera,lookat)
new(screen.vector,0,0,mousedepth)
new(Lxy.vector,LA\x,LA\y,0)
new(Lyz.vector,0,LA\y,LA\z)
new(Lxz.vector,LA\x,0,LA\z)
new(Sxy.vector,screen\x,screen\y,0)
new(Syz.vector,0,screen\y,screen\z)
new(Sxz.vector,screen\x,0,screen\z)
a = angle(Sxy,Lxy)
b = angle(Syz,Lyz)
c = angle(Sxz,Lxz)
If equal(Lxy,origin)+equal(Sxy,origin):a=0:EndIf
If equal(Lyz,origin)+equal(Syz,origin):b=0:EndIf
If equal(Lxz,origin)+equal(Sxz,origin):c=0:EndIf
new(angles.vector,b,c,a)
rotate(*v,angles)
translate(*v,camera)
EndProcedure
Procedure.d distance(*a.vector,*b.vector,*c.vector)
;distance between line AB and point C
new(AB.vector,*b\x-*a\x,*b\y-*a\y,*b\z-*a\z)
new(AC.vector,*c\x-*a\x,*c\y-*a\y,*c\z-*a\z)
angle.d = angle(AB,AC)
ProcedureReturn Pow(dot(AC,AC),0.5)*Sin(angle)
EndProcedure
Procedure over(*v.vector)
ForEach spheres()
Delay(0)
copy(centre.vector,spheres()\centre)
spheres()\distance=Pow(Pow(camera\x-centre\x,2)+Pow(camera\y-centre\y,2)+Pow(camera\z-centre\z,2),0.5)
basicangle.l = (180*angle(lookat,centre)/#PI)
If basicangle>90:spheres()\distance = -spheres()\distance:EndIf
Next
SortStructuredList(spheres(),0,OffsetOf(bounded\distance),#PB_Sort_Double)
ForEach spheres()
Delay(0)
If (spheres()\distance>=0) And (distance(camera,*v,spheres()\centre)<= spheres()\radius): ProcedureReturn spheres()\object:EndIf
Next
ProcedureReturn -1
EndProcedure
Procedure getMouse(*m.mouse)
ExamineMouse()
If MouseButton(#PB_MouseButton_Left)
*m\button=1
ElseIf MouseButton(#PB_MouseButton_Right)
*m\button=2
ElseIf MouseButton(#PB_MouseButton_Middle)
*m\button=3
Else
*m\button=0
EndIf
x = MouseX()-width/2
y = (height/2-MouseY())
z = mousedepth
new(v.vector,x,y,z)
map(v)
*m\x = MouseX()
*m\y = MouseY()
copy(*m\v,v)
*m\over = over(v)
EndProcedure
Procedure.s displayMouse(*m.mouse)
ProcedureReturn "("+Str(*m\x)+","+Str(*m\y)+") - ["+StrD(*m\v\x,2)+","+StrD(*m\v\y,2)+","+StrD(*m\v\z,2)+"] - distance "+StrD(Pow(Pow(*m\v\x - camera\x,2)+Pow(*m\v\y - camera\y,2)+Pow(*m\v\z - camera\z,2),0.5),2)
EndProcedure
Procedure setcamera(cameraID.l,*v.vector)
If *v <> #Null:copy(camera,*v):EndIf
CameraLocate(cameraID,*v\x,*v\y,*v\z)
If lookat <> #Null:new(lookat,0,0,-1000):EndIf
CameraLookAt(cameraID,lookat\x,lookat\y,lookat\z)
EndProcedure
Procedure setlookat(cameraID.l,*v.vector)
If *v <> #Null:copy(lookat,*v):EndIf
CameraLookAt(cameraID,lookat\x,lookat\y,lookat\z)
EndProcedure
Procedure addSphere(object.l,*centre.vector,radius.d)
AddElement(spheres())
spheres()\object = object
spheres()\centre\x = *centre\x
spheres()\centre\y = *centre\y
spheres()\centre\z = *centre\z
spheres()\radius = radius
EndProcedure
Procedure moveObject(object.l,*v.vector)
MoveEntity(object,*v\x,*v\y,*v\z)
SortStructuredList(spheres(),0,OffsetOf(bounded\object),#PB_Sort_Long)
ForEach spheres()
If spheres()\object = object:translate(spheres()\centre,*v):EndIf
If spheres()\object > object:ProcedureReturn:EndIf
Next
EndProcedure
;-Initialise
ExamineDesktops()
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(width,height,32,"")
UseJPEGImageDecoder()
UsePNGImageDecoder()
Add3DArchive("Data\", #PB_3DArchive_FileSystem)
Parse3DScripts()
LoadSprite(0,"Data\mouse.PNG")
;-Setup Movement Vectors
new(up.vector,0,0,-1):map(up)
new(down.vector,0,0,1):map(down)
new(left.vector,-1,0,0):map(left)
new(right.vector,1,0,0):map(right)
;-Set named Vectors
new(origin,0,0,0)
new(camera,0,0,0)
new(lookat,0,0,mousedepth)
;-Setup Camera
CreateCamera(0, 0, 0, 100, 100)
setcamera(0,camera)
setlookat(0,lookat)
CameraFOV(0, #PI / 3)
;-Setup Cubes
LoadMesh (1, "cube.mesh")
LoadTexture(1, "stone.jpg")
CreateMaterial(1,TextureID(1))
For i=1 To 1000
new(r.vector,2*Random(width)-width,2*Random(height)-height,-Random(-mousedepth))
CreateEntity(i,MeshID(1),MaterialID(1),r\x,r\y,r\z)
ScaleEntity(i,0.1,0.1,0.1)
addSphere(i,r,6.5)
Next i
;-Main loop
Repeat
ClearScreen(0)
RenderWorld()
getmouse(mouse.mouse)
StartDrawing(ScreenOutput())
DrawText(0,0, "Mouse location: "+displayMouse(mouse),$FFFF,0)
ovr = over(mouse\v)
If ovr<0
DrawText(0,16, "Mouse is over: nothing ",$FF,0)
Else
DrawText(0,16, "Mouse is over: object "+Str(ovr),$FF00,0)
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up)
moveObject(ovr,up)
ElseIf KeyboardPushed(#PB_Key_Down)
moveObject(ovr,down)
ElseIf KeyboardPushed(#PB_Key_Left)
moveObject(ovr,left)
ElseIf KeyboardPushed(#PB_Key_Right)
moveObject(ovr,right)
EndIf
EndIf
EndIf
StopDrawing()
DisplayTransparentSprite(0,MouseX(),MouseY())
FlipBuffers()
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)