DLP for Virtual Environments (II) Interaction between users and 3D objects Multiple Instances of 3D...

35
DLP for Virtual Environments (II) Interaction between users and 3D objects Multiple Instances of 3D Objects Rotation/Orientation calculation

Transcript of DLP for Virtual Environments (II) Interaction between users and 3D objects Multiple Instances of 3D...

DLP for Virtual Environments (II)

• Interaction between users and 3D objects

• Multiple Instances of 3D Objects

• Rotation/Orientation calculation

Design 3D Objects with prototype

•Design a prototype•Set an instantiated Object•Use DEF to define the name of the object.

Example: Bus

PROTO Bus [ exposedField SFVec3f translation 0 0 0 exposedField SFRotation rotation 0 1 0 0]

{Transform { translation IS translation

rotation IS rotation children [

......]}}

Transform {children [ DEF bus1 Bus { translation -5 0 -1.5 rotation 0 1 0 0} ] }

Interaction: get viewpoint•getSFVec3f(Viewpoint,position,X,Y,Z)

•getSFRotation(Viewpoint,orientation,X,Y,Z,R)

•getViewpointPosition(Viewpoint,X,Y,Z)

•getViewpointOrientation(Viewpoint,X,Y,Z,R)

Problem: those get-predicates output only the values are either initial values or values are set by the set-predicates. They ignore the effects of the keyboard and the mouse navigation.

Solution: Add proximity sensors.

Proximity SensorDEF proxSensor ProximitySensor {center 0 0 0

size 1000 1000 1000 enabled TRUE isActive TRUE}

• getSFVec3f(proxSensor,position,X,Y,Z)

for getting the position of the viewpoint

• getSFRotation(proxSensor,orientation,X,Y,Z,R)

for getting the orientation of the viewpoint

• Do not use setSFVec3f(proxSensor,position,X,Y,Z)

and setSFRotation(proxSensor,orientation,X,Y,Z,R)

Example: Bus Driving

:-object wasp2 : [bcilib].var url = './street/street5.wrl'.var timelimit = 300.

main :-text_area(Browser),set_output(Browser),format('Loading street1 from ~w~n', [url]),loadURL(url),format('The bus1 is going to jump in front of you in 5

seconds,~n'),format('then you can drive the bus for ~w seconds~n',

[timelimit]), delay(5000), jump(bus1),

drive(bus1,timelimit).

jump(Object) :-getSFVec3f(proxSensor,position,X,_Y,Z), Z1 is Z-5,

setPosition(Object,X, 0.0 ,Z1).

drive(_,0):-!.

drive(Object,N) :- N>0, N1 is N-1,format('time left: ~w seconds~n', [N]),

delay(1000), getSFVec3f(proxSensor,position,X,_Y,Z), getSFRotation(proxSensor,orientation,_X2,Y2,_Z2,R2), setPosition(Object,X, 0.0 ,Z), R3 is sign(Y2)*R2 + 1.571, setRotation(Object,0.0,1.0,0.0,R3),

drive(Object,N1).

:-end_object wasp2.

Rotations in VRMLRotation = <1, 0, 0, 1.57>

Right-hand Rule

Rotation Calculation (I)

Rotation Calculation (I)

R3= Y2*R2 + 1.57

=sign(Y2)*R2+1.57

Mathematics for Virtual Environments

• Point: <X,Y,Z>

•Vector = point2 – point1

• Vector cross product: v1 X v2

point2

point1

vector

v1

v2

v1 X v2 (Rotation axis:<x,y,z>)

R

Cross ProductThe cross product of two vectors is perpendicular to both;

the right hand rule picks the one out of two possible

perpendicular directions.

Vector Math for 3D Computer Graphicshttp://chortle.ccsu.edu/vectorLessons/vectorIndex.html

· Chapter 0 — Points in Space

· Chapter 1 — Vectors, Points, and Displacement

· Chapter 2 — Vector Addition

· Chapter 3 — Displacement Vectors

· Chapter 4 — Length of Vectors

· Chapter 5 — Direction of Vectors

· Chapter 6 — Scaling and Unit Vectors

· Chapter 7 — The Dot Product

· Chapter 8 — Length and the Dot Product

· Chapter 9 — The Angle between two Vectors.

· Chapter 10 — The Angle between 3D Vectors.

· Chapter 11 — Projecting one Vector onto Another.

· Chapter 12 — Vector Cross Product.

· Chapter 13 — Matrices and Simple Matrix Operations.

· Chapter 14 — Matrix-Column Matrix Multiplicaton.

· Chapter 15 — Matrix-Matrix Multiplication

· Chapter 16 — Identity Matrix and Matrix Inverse

Vectorlib in DLP• vector_cross_product(V1, V2, V, R)

• direction_vector(position(X1,Y1,Z1),position(X2,Y2,Z2),vector(X,Y,Z))

• vector_rotation(vector(X1,Y1,Z1),rotation(X,Y,Z,R),vector(X2,Y2,Z2)).

• position_rotation(position(X1,Y1,Z1),rotation(X,Y,Z,R),position(X2,Y2,Z2)

:-object wasp2v : [bcilib, vectorlib].

......

look_in_direction(Object, InitVector,DesVector):-

vector_cross_product(InitVector,DesVector,vector(X,Y,Z),R),

setRotation(Object,X,Y,Z,R).

drive(Object,N) :-

N > 0,

N1 is N-1,

format('time left: ~w seconds~n', [N]),

delay(1000),

getSFVec3f(proxSensor,position,X,_Y,Z),

getSFRotation(proxSensor,orientation,X2,Y2,Z2,R2),

setPosition(Object,X, 0.0 ,Z),

vector_rotation(vector(0,0,-1), rotation(X2,Y2,Z2,R2), vector(X3,Y3,Z3)),

look_in_direction(Object,vector(1,0,0),vector(X3,Y3,Z3)),

drive(Object,N1).

:-end_object wasp2v.

Example: Soccer Kicking

:-object wasp3 : [bcilib].var url = './soccer/soccer1b.wrl'.var timelimit = 300.

main :-text_area(Browser),set_output(Browser),format('Load the game ...~n'),loadURL(url),format('the game will start in 5 seconds,~n'),format('note that the total playing time period is ~w

seconds,~n', [timelimit]),delay(5000),format('the game startup,~n'),play_ball(me, ball).

play_ball(Agent, Ball) :--- timelimit,timelimit > 0, !,format('time left: ~w seconds~n', [timelimit]),delay(800),near_ball_then_kick(Agent, Ball),play_ball(Agent, Ball).

play_ball(_, _). /* capture-anything-else statement*/

near_ball_then_kick(Agent, Ball):-getViewpointPositionEx(Agent,X,_Y,Z),getPosition(Ball,X1,Y1,Z1),Xdif is X1-X, Zdif is Z1-Z,Dist is sqrt(Xdif*Xdif + Zdif*Zdif),Dist < 5, !,X2 is Xdif*3,Z2 is Zdif*3,X3 is X2 + X1,Z3 is Z2 + Z1,setPosition(Ball,X3,Y1,Z3).

near_ball_then_kick(_, _).

getViewpointPositionEx(_,X,Y,Z) :- getSFVec3f(proxSensor,position,X,Y,Z).

getViewpointOrientationEx(_,X,Y,Z,R):- getSFRotation(proxSensor,orientation,X,Y,Z,R).

:-end_object wasp3.

Example: Soccer Kicking 2

:-object wasp4 : [bcilib].var url = './soccer/soccer2b.wrl'.var timelimit = 500.

main :-text_area(Browser),set_output(Browser),format('Load the game ...~n'),loadURL(url),.....play_ball(me, ball).

play_ball(Agent, Ball) :- -- timelimit, timelimit > 0, !, format('time left: ~w seconds~n', [timelimit]),

delay(800),look_at_ball(goalKeeper1,Ball),near_ball_then_kick(Agent, Ball),play_ball(Agent, Ball).

play_ball(_, _).

near_ball_then_kick(Agent, Ball):-getViewpointPositionEx(Agent,X,_Y,Z),......X3 is X2 + X1,Z3 is Z2 + Z1,setPosition(Ball,X3,Y1,Z3),checkBallPosition(Ball,X3,Y1,Z3).

near_ball_then_kick(_, _).

checkBallPosition(Ball, X, Y, Z):-getPosition(goalKeeper1,X1,_Y1,Z1),Xdif is X-X1,Zdif is Z-Z1,Dist is sqrt(Xdif*Xdif + Zdif*Zdif),Dist < 4, !,X2 is X - 8,format('The goalkeeper kicks the ball back~n'),setPosition(Ball,X2,Y,Z).

checkBallPosition(_,_,_,_).

look_at_ball(Player,Ball):-getPosition(Player,X,_,Z),getPosition(Ball, X1,_,Z1),Xdif is X-X1,Xdif =\= 0.0,Zdif is Z1-Z,R is atan(Zdif/Xdif) - sign(Xdif)*1.571,setRotation(Player,0.0, 1.0, 0.0, R).

look_at_ball(_,_).

look_at_ball(Sportman,Ball):-getPosition(Sportman,_X,_,Z),getPosition(Ball, _X1,_,Z1),Z1 < Z,setRotation(Sportman,0.0, 1.0, 0.0, 3.14).

look_at_ball(Sportman,Ball):-getPosition(Sportman,_X,_,Z),getPosition(Ball, _X1,_,Z1),Z1 > Z,setRotation(Sportman,0.0, 1.0, 0.0, 0.0).

look_at_ball(_Player,_Ball):-!......

:-end_object wasp4.

Rotation Calculation (II)

R is atan(Zdif/Xdif) - sign(Xdif)*1.57

R = 3.14 if Z > Z1

R = 0.0 if Z < Z1

:-object wasp4v : [bcilib, vectorlib].......

look_at_ball(Sportman,Ball):-getPosition(Sportman,X,_Y,Z),getPosition(Ball, X1,_Y1,Z1),direction_vector(position(X,0,Z), position(X1,0,Z1),

vector(X2,Y2,Z2)),

look_in_direction(Sportman,vector(0,0,1),vector(X2,Y2,Z2)).

:-end_obect wasp4v.

Exercises

1.Improve the example of ball kicking so that the soccer ball can continuously move to a new position. It would not just simply jump to the new position.

2. Design a DLP program to control the bus moving so that it can move along a route (which is defined by a set of facts, thus, a database).

*3.(Bonus 5 marks)Improve the example of bus driving so that the user can start and stop the bus engine. Namely, the bus moves only after the engine starts, and the bus would not move if the engine stops.

Ball Moving

Ball Moving1. Move along a straight line constantly with Y-

parameter unchanged. (interpolation)

2. Move along a curve in Y-dimension with a height.

3. Move subjected to the physical law of gravity and acceleration:

x = x0+Vx*t

y = y0+Vy*t-1/2*g*t*t

z = z0+Vz*t

Ball Moving: Interpolation:-object wasp5 : [bcilib].var url = './soccer/soccer1b.wrl'.var timelimit = 500.var interpolation = 5.……near_ball_then_kick(Agent, Ball):-

getViewpointPositionEx(Agent,X,_Y,Z),getPosition(Ball,X1,Y1,Z1),Xdif is X1-X, Zdif is Z1-Z,Dist is sqrt(Xdif*Xdif + Zdif*Zdif),Dist < 5, !,

X2 is Xdif*3, Z2 is Zdif*3,X3 is X2 + X1, Z3 is Z2 + Z1,

move_to_position(Ball, position(X1,Y1,Z1), position(X3,Y1,Z3),interpolation).

near_ball_then_kick(-,-).

move_to_position(Ball,_,position(X,Y,Z),0):-

setPosition(Ball,X,Y,Z).

move_to_position(Ball, position(X1,Y1,Z1),

position(X2,Y2,Z2),C):-

C1 is C-1,

Xdif is X2 -X1,

Zdif is Z2 -Z1,

X is X1 + Xdif/C,

Z is Z1 + Zdif/C,

setPosition(Ball,X,Y1,Z),

sleep(100),

move_to_position(Ball,position(X,Y1,Z),

position(X2,Y2,Z2),C1).

:-end_object wasp5.

How to define a route

%route-point(route_id, point_index, X,Z)

route_point(1,0,0,0):-!.route_point(1,1,100,0):-!.route_point(1,2,100,50):-!.route_point(1,3,-100,50):-!.route_point(1,4,-100,-50):-!.route_point(1,5,100,-50):-!.route_point(1,6,100,0):-!.route_point(1,7,0,0):-!.

DLP programs would calculate the interpolations

between two route points and set the correct rotation for moving the bus to the next route point.

Interpolation: based on the move_to_position example

Rotation calculation: based on the look_in_direction example.

Hints