Hi all,
On Lee's
FPSC Reloaded blog, he asked for some help regarding picking a point on a terrain with the cursor, and since I also wanted to know this, I started experimenting.
At first I tried using the camera's FOV and calculating the angle, which theoretically should work but I must have been doing something wrong because I just couldn't get it to work. I'm sure it's a valid method, though...
So I starting researching it on the internet. In the end I decided it would be simplest to use the 3D Maths commands, however complicated. And it took literally a day and half of more-or-less constant work and a
Stack Overflow question before I finally got it to work. Sure, I could have asked on these forums and someone would probably have been able to give me code right off the bat, but I wanted to do it myself.
And I did. It works. And I have a much better understanding of how things are rendered.
Following is the source code, in case anyone wants it. It requires
Sparky's DLL (I did NOT know Sparky is Paul Johnston...very cool that he
released the source code) if you want to run it as it is, but it can be used with any raycasting plugin (such as
Dark Dynamix):
sync on
sync rate 0
autocam off
set display mode desktop width(),desktop height(),32,1
sync
global camrange=1000
global screenwidth#=0.0 //in vars to force floating maths
global screenheight#=0.0
screenwidth#=desktop width()
screenheight#=desktop height()
load object "test.x",1
make object sphere 2,0.4 //hit indicator
color object 2,rgb(255,0,0) //make the indicator bright red
//position object 1,0,0,80
sc_setupobject 1,0,0
move camera -80
move camera right 50
set camera range 1,1000
global m4_view=1
global m4_projection=2
global m4_viewproj=3
global v4_near=4
global v4_far=5
global v3_far=6
blank=make matrix4(m4_view)
blank=make matrix4(m4_projection)
blank=make matrix4(m4_viewproj)
blank=make vector4(v4_near)
blank=make vector4(v4_far)
blank=make vector3(v3_far)
projection matrix4 m4_projection
do
set cursor 0,0
print ""
print ""
print "HOLD RMB TO ROTATE CAMERA AND USE ARROW KEYS TO MOVE CAMERA"
view matrix4 m4_view //only necessary to update this matrix when the camera changes position/rotation
set vector4 v4_near,((mousex()/screenwidth#)*2)-1,-(((mousey()/screenheight#)*2)-1),0,1
set vector4 v4_far,((mousex()/screenwidth#)*2)-1,-(((mousey()/screenheight#)*2)-1),1,1
multiply matrix4 m4_viewproj,m4_view,m4_projection
blank=inverse matrix4(m4_viewproj,m4_viewproj)
transform vector4 v4_near,v4_near,m4_viewproj
transform vector4 v4_far,v4_far,m4_viewproj
set vector3 v3_far,x vector4(v4_far),y vector4(v4_far),z vector4(v4_far) //normalisation would be affected if it were a vec4
normalize vector3 v3_far,v3_far
multiply vector3 v3_far,camrange
hit=sc_raycast(1,x vector4(v4_near),y vector4(v4_near),z vector4(v4_near),x vector3(v3_far),y vector3(v3_far),z vector3(v3_far),0)
if hit=1 then position object 2,sc_getstaticcollisionx(),sc_getstaticcollisiony(),sc_getstaticcollisionz()
gosub _cameracontrol
sync
loop
_cameracontrol:
if mouseclick()=2
hide mouse
movex#=mousemovex()/10.0
movey#=mousemovey()/10.0
yrotate camera camera angle y()+(movex#+oldmovex#)/2.0
xrotate camera camera angle x()+(movey#+oldmovey#)/2.0
position mouse screen width()/2,screen height()/2
oldmovex#=movex#
oldmovey#=movey#
if camera angle x()>90 then rotate camera 90,camera angle y(),camera angle z()
if camera angle x()<-90 then rotate camera -90,camera angle y(),camera angle z()
if camera angle y()>360 then rotate camera camera angle x(),0,camera angle z()
if camera angle y()<0 then rotate camera camera angle x(),360,camera angle z()
else
show mouse
endif
if upkey()=1 then move camera 1
if downkey()=1 then move camera -1
if leftkey()=1 then move camera left 1
if rightkey()=1 then move camera right 1
return
If anyone doesn't understand it and really wants to use it I'm happy to provide detailed tutorials, or if you prefer just show you which bits to use
Oh, and here's the model file that it loads as a test. It's .x format, so just stick it in a text editor (notepad) and save as .x
xof 0303txt 0032
Frame Root {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000,-0.000000, 1.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}
Frame Cone {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000,-1.541744, 1.970599, 1.000000;;
}
Mesh { // Cone mesh
33;
0.000000; 1.000000;-1.000000;,
0.195090; 0.980785;-1.000000;,
0.382683; 0.923880;-1.000000;,
0.555570; 0.831470;-1.000000;,
0.707107; 0.707107;-1.000000;,
0.831470; 0.555570;-1.000000;,
0.923880; 0.382683;-1.000000;,
0.980785; 0.195090;-1.000000;,
1.000000; 0.000000;-1.000000;,
0.000000; 0.000000; 1.000000;,
0.980785;-0.195090;-1.000000;,
0.923880;-0.382683;-1.000000;,
0.831470;-0.555570;-1.000000;,
0.707107;-0.707107;-1.000000;,
0.555570;-0.831470;-1.000000;,
0.382683;-0.923880;-1.000000;,
0.195090;-0.980785;-1.000000;,
-0.000000;-1.000000;-1.000000;,
-0.195091;-0.980785;-1.000000;,
-0.382684;-0.923879;-1.000000;,
-0.555571;-0.831469;-1.000000;,
-0.707107;-0.707106;-1.000000;,
-0.831470;-0.555570;-1.000000;,
-0.923880;-0.382683;-1.000000;,
-0.980785;-0.195089;-1.000000;,
-1.000000; 0.000001;-1.000000;,
-0.980785; 0.195091;-1.000000;,
-0.923879; 0.382684;-1.000000;,
-0.831469; 0.555571;-1.000000;,
-0.707106; 0.707108;-1.000000;,
-0.555569; 0.831470;-1.000000;,
-0.382682; 0.923880;-1.000000;,
-0.195089; 0.980786;-1.000000;;
33;
3;32,9,31;,
3;1,9,0;,
3;0,9,32;,
3;2,9,1;,
3;31,9,30;,
3;30,9,29;,
3;29,9,28;,
3;28,9,27;,
3;27,9,26;,
3;26,9,25;,
3;25,9,24;,
3;24,9,23;,
3;23,9,22;,
3;22,9,21;,
3;21,9,20;,
3;20,9,19;,
3;19,9,18;,
3;18,9,17;,
3;17,9,16;,
3;16,9,15;,
3;15,9,14;,
3;14,9,13;,
3;13,9,12;,
3;12,9,11;,
3;11,9,10;,
3;10,9,8;,
3;8,9,7;,
3;7,9,6;,
3;6,9,5;,
3;5,9,4;,
3;4,9,3;,
3;3,9,2;,
32;32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,8,7,6,5,4,3,2,1,0;;
MeshNormals { // Cone normals
33;
-0.259887; 0.856737; 0.445488;,
0.087754; 0.890977; 0.445488;,
-0.087753; 0.890977; 0.445488;,
0.259888; 0.856737; 0.445488;,
-0.422035; 0.789574; 0.445488;,
-0.567964; 0.692067; 0.445488;,
-0.692066; 0.567965; 0.445488;,
-0.789573; 0.422037; 0.445488;,
-0.856737; 0.259889; 0.445488;,
-0.890977; 0.087754; 0.445488;,
-0.890977;-0.087753; 0.445488;,
-0.856737;-0.259887; 0.445488;,
-0.789574;-0.422035; 0.445488;,
-0.692067;-0.567964; 0.445488;,
-0.567965;-0.692066; 0.445488;,
-0.422036;-0.789573; 0.445488;,
-0.259889;-0.856737; 0.445488;,
-0.087754;-0.890977; 0.445488;,
0.087753;-0.890977; 0.445488;,
0.259888;-0.856737; 0.445488;,
0.422036;-0.789573; 0.445488;,
0.567965;-0.692067; 0.445488;,
0.692067;-0.567965; 0.445488;,
0.789573;-0.422035; 0.445488;,
0.856737;-0.259888; 0.445488;,
0.890977;-0.087753; 0.445488;,
0.890977; 0.087754; 0.445488;,
0.856737; 0.259888; 0.445488;,
0.789573; 0.422036; 0.445488;,
0.692067; 0.567965; 0.445488;,
0.567965; 0.692067; 0.445488;,
0.422036; 0.789573; 0.445488;,
0.000000; 0.000000;-1.000000;;
33;
3;0,0,0;,
3;1,1,1;,
3;2,2,2;,
3;3,3,3;,
3;4,4,4;,
3;5,5,5;,
3;6,6,6;,
3;7,7,7;,
3;8,8,8;,
3;9,9,9;,
3;10,10,10;,
3;11,11,11;,
3;12,12,12;,
3;13,13,13;,
3;14,14,14;,
3;15,15,15;,
3;16,16,16;,
3;17,17,17;,
3;18,18,18;,
3;19,19,19;,
3;20,20,20;,
3;21,21,21;,
3;22,22,22;,
3;23,23,23;,
3;24,24,24;,
3;25,25,25;,
3;26,26,26;,
3;27,27,27;,
3;28,28,28;,
3;29,29,29;,
3;30,30,30;,
3;31,31,31;,
32;32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32;;
} // End of Cone normals
} // End of Cone mesh
} // End of Cone
Frame Cube {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}
Mesh { // Cube mesh
8;
1.000000; 1.000000;-1.000000;,
1.000000;-1.000000;-1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000; 1.000000;-1.000000;,
1.000000; 0.999999; 1.000000;,
0.999999;-1.000001; 1.000000;,
-1.000000;-1.000000; 1.000000;,
-1.000000; 1.000000; 1.000000;;
6;
4;3,2,1,0;,
4;5,6,7,4;,
4;1,5,4,0;,
4;2,6,5,1;,
4;3,7,6,2;,
4;7,3,0,4;;
MeshNormals { // Cube normals
6;
0.000000; 0.000000;-1.000000;,
0.000000;-0.000000; 1.000000;,
1.000000;-0.000000; 0.000000;,
-0.000000;-1.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
0.000000; 1.000000; 0.000000;;
6;
4;0,0,0,0;,
4;1,1,1,1;,
4;2,2,2,2;,
4;3,3,3,3;,
4;4,4,4,4;,
4;5,5,5,5;;
} // End of Cube normals
MeshMaterialList { // Cube material list
1;
6;
0,
0,
0,
0,
0,
0;;
Material Material {
0.640000; 0.640000; 0.640000; 1.000000;;
96.078431;
0.500000; 0.500000; 0.500000;;
0.000000; 0.000000; 0.000000;;
}
} // End of Cube material list
} // End of Cube mesh
} // End of Cube
Frame Icosphere {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
-1.403176, 1.515785, 1.160112, 1.000000;;
}
Mesh { // Icosphere mesh
42;
0.000000; 0.000000;-1.000000;,
0.723607;-0.525725;-0.447220;,
-0.276388;-0.850649;-0.447220;,
-0.894426; 0.000000;-0.447216;,
-0.276388; 0.850649;-0.447220;,
0.723607; 0.525725;-0.447220;,
0.276388;-0.850649; 0.447220;,
-0.723607;-0.525725; 0.447220;,
-0.723607; 0.525725; 0.447220;,
0.276388; 0.850649; 0.447220;,
0.894426; 0.000000; 0.447216;,
0.000000; 0.000000; 1.000000;,
0.425323;-0.309011;-0.850654;,
0.262869;-0.809012;-0.525738;,
-0.162456;-0.499995;-0.850654;,
0.425323; 0.309011;-0.850654;,
0.850648; 0.000000;-0.525736;,
-0.688189;-0.499997;-0.525736;,
-0.525730; 0.000000;-0.850652;,
-0.688189; 0.499997;-0.525736;,
-0.162456; 0.499995;-0.850654;,
0.262869; 0.809012;-0.525738;,
0.951058; 0.309013; 0.000000;,
0.951058;-0.309013; 0.000000;,
0.587786;-0.809017; 0.000000;,
0.000000;-1.000000; 0.000000;,
-0.587786;-0.809017; 0.000000;,
-0.951058;-0.309013; 0.000000;,
-0.951058; 0.309013; 0.000000;,
-0.587786; 0.809017; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.587786; 0.809017; 0.000000;,
0.688189;-0.499997; 0.525736;,
-0.262869;-0.809012; 0.525738;,
-0.850648; 0.000000; 0.525736;,
-0.262869; 0.809012; 0.525738;,
0.688189; 0.499997; 0.525736;,
0.525730; 0.000000; 0.850652;,
0.162456;-0.499995; 0.850654;,
-0.425323;-0.309011; 0.850654;,
-0.425323; 0.309011; 0.850654;,
0.162456; 0.499995; 0.850654;;
80;
3;14,12,0;,
3;16,12,1;,
3;18,14,0;,
3;20,18,0;,
3;15,20,0;,
3;23,16,1;,
3;25,13,2;,
3;27,17,3;,
3;29,19,4;,
3;31,21,5;,
3;24,23,1;,
3;26,25,2;,
3;28,27,3;,
3;30,29,4;,
3;22,31,5;,
3;38,32,6;,
3;39,33,7;,
3;40,34,8;,
3;41,35,9;,
3;37,36,10;,
3;2,13,14;,
3;13,12,14;,
3;13,1,12;,
3;5,15,16;,
3;15,12,16;,
3;15,0,12;,
3;3,17,18;,
3;17,14,18;,
3;17,2,14;,
3;4,19,20;,
3;19,18,20;,
3;19,3,18;,
3;5,21,15;,
3;21,20,15;,
3;21,4,20;,
3;10,22,23;,
3;22,16,23;,
3;22,5,16;,
3;6,24,25;,
3;24,13,25;,
3;24,1,13;,
3;7,26,27;,
3;26,17,27;,
3;26,2,17;,
3;8,28,29;,
3;28,19,29;,
3;28,3,19;,
3;9,30,31;,
3;30,21,31;,
3;30,4,21;,
3;6,32,24;,
3;32,23,24;,
3;32,10,23;,
3;7,33,26;,
3;33,25,26;,
3;33,6,25;,
3;8,34,28;,
3;34,27,28;,
3;34,7,27;,
3;9,35,30;,
3;35,29,30;,
3;35,8,29;,
3;10,36,22;,
3;36,31,22;,
3;36,9,31;,
3;11,37,38;,
3;37,32,38;,
3;37,10,32;,
3;11,38,39;,
3;38,33,39;,
3;38,6,33;,
3;11,39,40;,
3;39,34,40;,
3;39,7,34;,
3;11,40,41;,
3;40,35,41;,
3;40,8,35;,
3;11,41,37;,
3;41,36,37;,
3;41,9,36;;
MeshNormals { // Icosphere normals
80;
0.102381;-0.315090;-0.943523;,
0.700224;-0.268032;-0.661699;,
-0.268034;-0.194736;-0.943523;,
-0.268034; 0.194737;-0.943523;,
0.102381; 0.315090;-0.943523;,
0.904989;-0.268032;-0.330385;,
0.024747;-0.943521;-0.330386;,
-0.889697;-0.315095;-0.330385;,
-0.574602; 0.748784;-0.330388;,
0.534576; 0.777865;-0.330387;,
0.802609;-0.583126;-0.125627;,
-0.306569;-0.943522;-0.125629;,
-0.992077;-0.000000;-0.125628;,
-0.306569; 0.943522;-0.125629;,
0.802609; 0.583126;-0.125627;,
0.408946;-0.628425; 0.661698;,
-0.471300;-0.583122; 0.661699;,
-0.700224; 0.268032; 0.661699;,
0.038530; 0.748779; 0.661699;,
0.724042; 0.194736; 0.661695;,
-0.038530;-0.748779;-0.661699;,
0.187594;-0.577345;-0.794658;,
0.471300;-0.583122;-0.661699;,
0.700224; 0.268032;-0.661699;,
0.607060; 0.000000;-0.794656;,
0.331305; 0.000000;-0.943524;,
-0.724042;-0.194736;-0.661695;,
-0.491119;-0.356821;-0.794657;,
-0.408946;-0.628425;-0.661698;,
-0.408946; 0.628425;-0.661698;,
-0.491119; 0.356821;-0.794657;,
-0.724042; 0.194736;-0.661695;,
0.471300; 0.583122;-0.661699;,
0.187594; 0.577345;-0.794658;,
-0.038530; 0.748779;-0.661699;,
0.992077; 0.000000; 0.125628;,
0.982246; 0.000000;-0.187599;,
0.904989; 0.268031;-0.330385;,
0.306569;-0.943522; 0.125629;,
0.303531;-0.934171;-0.187597;,
0.534576;-0.777865;-0.330387;,
-0.802609;-0.583126; 0.125627;,
-0.794656;-0.577348;-0.187595;,
-0.574602;-0.748784;-0.330388;,
-0.802609; 0.583126; 0.125627;,
-0.794656; 0.577348;-0.187595;,
-0.889697; 0.315095;-0.330385;,
0.306569; 0.943522; 0.125629;,
0.303531; 0.934171;-0.187597;,
0.024747; 0.943521;-0.330386;,
0.574602;-0.748784; 0.330388;,
0.794656;-0.577348; 0.187595;,
0.889697;-0.315095; 0.330385;,
-0.534576;-0.777865; 0.330387;,
-0.303531;-0.934171; 0.187597;,
-0.024747;-0.943521; 0.330386;,
-0.904989; 0.268032; 0.330385;,
-0.982246; 0.000000; 0.187599;,
-0.904989;-0.268031; 0.330385;,
-0.024747; 0.943521; 0.330386;,
-0.303531; 0.934171; 0.187597;,
-0.534576; 0.777865; 0.330387;,
0.889697; 0.315095; 0.330385;,
0.794656; 0.577348; 0.187595;,
0.574602; 0.748784; 0.330388;,
0.268034;-0.194737; 0.943523;,
0.491119;-0.356821; 0.794657;,
0.724042;-0.194736; 0.661695;,
-0.102381;-0.315090; 0.943523;,
-0.187594;-0.577345; 0.794658;,
0.038530;-0.748779; 0.661699;,
-0.331305; 0.000000; 0.943524;,
-0.607060; 0.000000; 0.794656;,
-0.700224;-0.268032; 0.661699;,
-0.102381; 0.315090; 0.943523;,
-0.187594; 0.577345; 0.794658;,
-0.471300; 0.583122; 0.661699;,
0.268034; 0.194737; 0.943523;,
0.491119; 0.356821; 0.794657;,
0.408946; 0.628425; 0.661699;;
80;
3;0,0,0;,
3;1,1,1;,
3;2,2,2;,
3;3,3,3;,
3;4,4,4;,
3;5,5,5;,
3;6,6,6;,
3;7,7,7;,
3;8,8,8;,
3;9,9,9;,
3;10,10,10;,
3;11,11,11;,
3;12,12,12;,
3;13,13,13;,
3;14,14,14;,
3;15,15,15;,
3;16,16,16;,
3;17,17,17;,
3;18,18,18;,
3;19,19,19;,
3;20,20,20;,
3;21,21,21;,
3;22,22,22;,
3;23,23,23;,
3;24,24,24;,
3;25,25,25;,
3;26,26,26;,
3;27,27,27;,
3;28,28,28;,
3;29,29,29;,
3;30,30,30;,
3;31,31,31;,
3;32,32,32;,
3;33,33,33;,
3;34,34,34;,
3;35,35,35;,
3;36,36,36;,
3;37,37,37;,
3;38,38,38;,
3;39,39,39;,
3;40,40,40;,
3;41,41,41;,
3;42,42,42;,
3;43,43,43;,
3;44,44,44;,
3;45,45,45;,
3;46,46,46;,
3;47,47,47;,
3;48,48,48;,
3;49,49,49;,
3;50,50,50;,
3;51,51,51;,
3;52,52,52;,
3;53,53,53;,
3;54,54,54;,
3;55,55,55;,
3;56,56,56;,
3;57,57,57;,
3;58,58,58;,
3;59,59,59;,
3;60,60,60;,
3;61,61,61;,
3;62,62,62;,
3;63,63,63;,
3;64,64,64;,
3;65,65,65;,
3;66,66,66;,
3;67,67,67;,
3;68,68,68;,
3;69,69,69;,
3;70,70,70;,
3;71,71,71;,
3;72,72,72;,
3;73,73,73;,
3;74,74,74;,
3;75,75,75;,
3;76,76,76;,
3;77,77,77;,
3;78,78,78;,
3;79,79,79;;
} // End of Icosphere normals
} // End of Icosphere mesh
} // End of Icosphere
} // End of Root