\chapter[DLP and Virtual Worlds]{DLP and Virtual Worlds} \label{dlp-on-vw} \label{dlpve} \section{VRML EAI and DLP} VRML EAI stands for the external authoring interface of the virtual reality modeling language. The EAI allows developers to control the contents of a VRML world. A VRML specification can be loaded in a browser by an application, such as a Java applet. As mentioned, DLP programs are compiled to Java classes, which can be used as Java applets in Web Browsers. DLP has been extended with a VRML EAI library, called (\inx{bcilib}). For instance, in the \inx{DLP VRML library}, the predicate $getSFVec3f(Object,Field,X,Y,Z)$ gets the $SFVec3f$ value (which consists of three float numbers $X$, $Y$, and $Z$) of the $Field$ of object $Object$, and $setSFVec3f(Object,Field,X,Y,Z)$ assigns $X$, $Y$, and $Z$ values to the $SFVec3f$ $Field$ in $Object$, where $Object$ refers to an object in a 3D VRML world. A DLP program can manipulate VRML virtual worlds by using the VRML EAI library predicates. Before we introduce more details of the DLP VRML predicates, we discuss first how to design VRML worlds that can be accessed from DLP programs. \section{Design 3D Virtual Worlds for DLP} 3D virtual worlds are implemented in VRML and the VRML EAI predicates refer to objects in the current virtual world which is loaded into a web browser. Each VRML file contains a \inx{scene graph hierarchy}\inxx{scene graph} which consists of \inx{VRML nodes}. Node statements may contain \inx{SFNode} or \inx{MFNode} \inx{field statements} that contain other node statements. Objects which can be manipulated by DLP programs are nodes which have names defined by \inx{DEF statements} in VRML. We use DEF to define object names of VRML nodes, and use DLP VRML predicates to manipulate the values of the fields of the defined nodes. For example, the following specification defines a yellow cylinder in VRML. \begin{verbatim} #VRML V2.0 utf8 Transform { translation 0 0 0 rotation 0 1 0 0 children [Shape {appearance Appearance { material Material {diffuseColor 1.0 1.0 0.0}} geometry Cylinder { height 2.0 radius 1.0}}]} \end{verbatim} In order to manipulate the values of the field 'translation' and the field 'rotation' of the cylinder, we have to define a name for the node 'Transform' as follows. \begin{verbatim} #VRML V2.0 utf8 DEF cylinder Transform { translation 0 0 0 rotation 0 1 0 0 children [Shape {appearance Appearance { material Material {diffuseColor 1.0 1.0 0.0}} geometry Cylinder { height 2.0 radius 1.0}}]} \end{verbatim} Note that we do not define the name of fields. More generally, we can define a prototype of a partial hierarchy first, so we can use such a prototype to create multiple instances of 3D objects. For example, the specification of a bus whose position and orientation can be controlled by DLP programs, consists of the following three steps: \begin{enumerate} \item Design a prototype for a bus; \item Instantiate the bus prototype; \item Use DEF to define the name of the bus. \end{enumerate} The corresponding VRML description is as follows: \begin{verbatim} 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} ] } \end{verbatim} Thus, $setSFVec3f(bus1, translation, 15, 0, -1.5)$ sets $bus1$ to a new position $\langle -15, 0, -1.5\rangle$. Similarly, we can use the same method to manipulate a viewpoint in a VRML world, namely, we define a viewpoint first and then use the viewpoint predicates \[getViewpointPosition(Viewpoint, X, Y,Z)\] and \[setViewpointPosition(Viewpoint, X,Y,Z)\] to set and get the values of a viewpoint that's defined as: \begin{verbatim} DEF myviewpoint Viewpoint { position -10 1.75 0 orientation 0 1 0 -1.5708 set_bind TRUE} \end{verbatim} Since VRML allows multiple viewpoints in a virtual world, we can only get the field values of the initial viewpoint unless we use explicitly the corresponding set-predicates. In the example above, calling $getViewpointPosition(myviewpoint, X,Y,Z)$, gets the result $X=-10.0$, $Y=1.75$, and $Z=0.0$ no matter how the user changes the viewpoint in the virtual world. In most applications, we want to get the current position of the user's viewpoint which may be changed by using the keyboard or mouse for navigation. This can be done by adding a proximity sensor to the virtual world: \begin{verbatim} DEF proxSensor ProximitySensor {center 0 0 0 size 1000 1000 1000 enabled TRUE isActive TRUE} \end{verbatim} Here we specify a proximity sensor with the size ($1000 \times 1000 \times 1000)$. Of course, the parameters should be changed for different applications. Getting the position and the rotation of the proximity sensor means getting the current values of the user's viewpoint. Therefore, we can define the extended get-viewpoint predicates as: \begin{verbatim} getViewpointPositionEx(_,X,Y,Z) :- getSFVec3f(proxSensor,position,X,Y,Z). getViewpointOrientationEx(_,X,Y,Z,R):- getSFRotation(proxSensor,orientation,X,Y,Z,R). \end{verbatim} \section{Loading 3D Virtual Worlds} 3D virtual worlds have to be loaded in a web browser for program manipulation, which can be done as follows: \begin{enumerate} \item Virtual worlds embedded in html files: \begin{verbatim} DLP-BCI example 1 \end{verbatim} Where $root.wrl$ is the initial VRML file which is stored in the directory $"./vrml"$, DLP classes directory is $"./classes"$, archive="dlpsys.jar" means that the DLP system library is "dlpsys.jar", code="dlpbrow.class" says that DLP is initialized by the class 'dlpbrow', which creates a text area in the browser that serves as a message output window for DLP. The statements $$ and $$ define the columns and rows of the text area. If 'dlpbrow.class' is replaced by another class 'dlpcons.class', this message window does not appear in the browser and all messages will be forwarded to the browser's built-in Java console. MAYSCRIPT states that java scripts are enabled. $$ states that the DLP program which manipulates the virtual worlds is "example1". \item Load virtual worlds for manipulation, by using the DLP VRML predicate $loadURL(URL)$. For example, $loadURL("example1.wrl")$ loads the virtual world $"example1.wrl"$ into the web browser. \end{enumerate} \section{VRML Predicates} We call VRML predicates which can be used for getting values {\em \inx{get-predicates}}, and predicates for setting values {\em \inx{set-predicates}}. The DLP VRML library (bcilib) offers a complete collection of get/set-predicates for all field types in VRML. Here are some VRML predicates from the DLP VRML EAI library: \begin{itemize} \item Single Field Predicates \begin{itemize} \item $getSFBool(+Object,+Field,-Bool)$ \item $setSFBool(+Object,+Field,+Bool)$ \item $getSFFloat(+Object,+Field,-Float)$ \item $setSFFloat(+Object,+Field,+Float)$ \item $getSFInt32(+Object,+Field,-Int32)$ \item $setSFInt32(+Object,+Field,+Int32)$ \item $getSFString(+Object,+Field,-Atom)$ \item $setSFString(+Object,+Field,+Atom)$ \item $getSFTime(+Object,+Field,-Time)$ \item $setSFTime(+Object,+Field,+Time)$ \item $getSFColor(+Object,+Field,-R,-G,-B)$ \item $setSFColor(+Object,+Field,+R,+G,+B)$ \item $getSFVec2f(+Object,+Field,-X,-Y)$ \item $setSFVec2f(+Object,+Field,+X,+Y)$ \item $getSFVec3f(+Object,+Field,-X,-Y,-Z)$ \item $setSFVec3f(+Object,+Field,+X,+Y,+Z)$ \end{itemize} For instance, $setSFVec3f(OtherViewpointNode, position, X, Y, Z)$ sets the position of another viewpoint node with values $X,Y,Z$, and $getSFVec3f(OtherViewpointNode, position, X,Y,Z)$ returns the position of the other viewpoint node in the variables $X,Y$, and $Z$ respectively. \item Multi Field Predicates \begin{itemize} \item $getMFFloat(+Object,+Field,-FloatList)$ \item $setMFFloat(+Object,+Field,+FloatList)$ \item $getMFInt32(+Object,+Field,-IntegerList)$ \item $setMFInt32(+Object,+Field,+IntegerList)$ \item $getMFString(+Object,+Field,-AtomList)$ \item $setMFString(+Object,+Field,+AtomList)$ \item $getMFColor(+Object,+Field,-RGBList)$ \item $setMFColor(+Object,+Field,+RGBList)$ \\ where $RGBList = [ [R1,G1,B1], [R2,G2,B2], .... ] $ \item $getMFVec2f(+Object,+Field,-XYList)$ \item $setMFVec2f(+Object,+Field,+XYList)$ \item $getMFVec3f(+Object,+Field,-XYZList)$ \item $setMFVec3f(+Object,+Field,+XYZList)$ \\ $XYList = [ [X1,Y1], [X2,Y2], .... ]$ \\ $ XYZList = [ [X1,Y1,Z1], [X2,Y2,Z2], .... ]$ \end{itemize} \item Agent / Object Coordinates \begin{itemize} \item $getPosition(+Object,-X,-Y,-Z)$ \item $setPosition(+Object,+X,+Y,+Z)$ \item $getRotation(+Object,-X,-Y,-Z,-R)$ \item $setRotation(+Object,+X,+Y,+Z,+R)$ \item $getViewpointPosition(+Viewpoint,-X,-Y,-Z)$ \item $setViewpointPosition(+Viewpoint,+X,+Y,+Z)$ \item $getViewpointOrientation(+Viewpoint,-X,-Y,-Z,-R)$ \item $setViewpointOrientation(+Viewpoint,+X,+Y,+Z,+R)$ \end{itemize} \end{itemize} In the VRML EAI library, the viewpoint predicates above manipulate a node $'Viewpoint'$, the default name of the viewpoint. However, in order to manipulate other viewpoints with non-default names, we can use generic predicates, like \[getSFVec3f(Viewpoint,position,X,Y,Z)\] and \[setSFVec3f(Viewpoint,position,X,Y,Z).\] Note that DLP programs which want to use VRML predicates to manipulate 3D objects should make the DLP VRML library $bcilib$ available for it. This can be done by inheritance. Namely, the first line of DLP programs should be like: \begin{verbatim} :-object objectname : [bcilib]. \end{verbatim} \section{Manipulating VRML worlds: Examples} In this section, we discuss how we can use DLP VRML predicates to control the contents of virtual worlds by a number of examples. \subsection{title moving} In this subsection, we discuss several examples to achieve the effect of title moving, like those at the beginning of TV programs and movies. A screenshot is shown in Figure \ref{title-moving0}. \begin{figure} \label{title-moving0} \resizebox*{7.5cm}{!}{\includegraphics{title-move0.jpg}} \caption{Screenshot of title moving} \end{figure} First we use VRML to design a virtual world in which there is a tunnel, i.e., a big cylinder with no bottom, and with the texture 'star1.jpg' as its background to simulate a star sky. Moreover, we also specify several texts which are located at the tunnel, and a music file 'mozart38.wav' to add sound. The 3D virtual world can be specified as follows in a file 'title0.wrl'. \begin{verbatim} #VRML V2.0 utf8 Background {skyColor [0.0 0.0 1.0] groundColor [0.0 0.0 1.0]} DEF myViewpoint Viewpoint { position 0 3 6 orientation 0 1 0 0} Transform { translation 0 3 0 rotation 1 0 0 1.57 children [Transform {translation 0 0 0 rotation 0 1 0 0 children Shape {appearance Appearance { texture ImageTexture { url "star1.jpg" repeatS TRUE repeatT TRUE } textureTransform TextureTransform {scale 30 10} material Material {diffuseColor 0.0 0.0 1.0 emissiveColor 1.0 1.0 1.0}} geometry Cylinder { height 2000 radius 2.5 top TRUE bottom FALSE}} }]} Transform {translation -2 3 50 scale 0.3 0.3 0.3 children [Shape {appearance Appearance { material Material {diffuseColor 1 1 0 emissiveColor 1 0 0}}} Text { string "Intelligent Multimedia Technology" }] } Transform {translation -2 3 30 scale 0.3 0.3 0.3 children [Shape {appearance Appearance { material Material {diffuseColor 1 1 0 emissiveColor 1 0 0}}} Text { string "Distributed Logic Programming" }] } Transform {translation -2 3 10 scale 0.3 0.3 0.3 children [Shape {appearance Appearance { material Material {diffuseColor 1 1 0 emissiveColor 1 0 0}}} Text { string "VRML+JAVA+PROLOG" }] } Transform {translation -2 3 -10 scale 0.3 0.3 0.3 children [Shape {appearance Appearance { material Material {diffuseColor 1 1 0 emissiveColor 1 0 0}}} Text { string "Multimedia Authoring" }] } Transform {translation -2 3 -30 scale 0.3 0.3 0.3 children [Shape {appearance Appearance { material Material {diffuseColor 1 1 0 emissiveColor 1 0 0}}} Text { string "Thank You Very Much!" }] } Sound {maxBack 2000 maxFront 2000 minFront 1000 minBack 1000 intensity 20 source AudioClip { loop TRUE url ["mozart38.wav"]}} \end{verbatim} In order to achieve an animation effect, we design a DLP program so that the viewpoint can be changed regularly. Thus, we add a defined name 'myViewpoint' to define the viewpoint in the virtual world. The DLP program 'titlemove0.pl' is shown below: \begin{verbatim} :-object titlemove0: [bcilib]. var count = 3000. var increment = 0.15. var url='./title/title0.wrl'. main :- text_area(Browser), set_output(Browser), loadURL(url), sleep(3000), move_title(count). move_title(0):-!. move_title(N):- N>0, N1 is N-1, getSFVec3f(myViewpoint,position, X,Y,Z), Znew is Z - increment, setSFVec3f(myViewpoint, position,X,Y,Znew), sleep(150), move_title(N1). :-end_object titlemove0. \end{verbatim} In order to let the format function in DLP programs to send its output to the web browser, we use the following clauses to set a text area as the output of the program: \begin{verbatim} text_area(Browser), set_output(Browser), \end{verbatim} However, note that if we set code="dlpcons.class" in the html file, the message window is not enabled in the browser, and the two lines above should not be used in the program. In the program, the viewpoint's position is gradually moving to the negative Z-direction by decreasing the Z value 0.15 meter each time. This is a simple example that shows how to manipulate 3D objects to achieve animation in virtual worlds. \subsection{Bus Driving} In this example, we design a bus driving program. Assume we have designed a bus in a VRML world, whose url is: \\\\ {\tt ./street1.wrl}\\ \\ Driving the bus implies setting the position and rotation of the bus according to the user's viewpoint. Moreover, the position and rotation of the bus should be changed whenever the user's viewpoint changes. Here is the bus driving program, which first loads the url and moves the bus in front of the user, then starts the driving procedure. \\ \\ \begin{verbatim} :-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. \end{verbatim} In the program, the $jump$ rules will move the bus in front of the user, or more exactly, the viewpoint of the virtual world. The $drive$ rules move the bus, i.e. the bus position and rotation are regularly updated according to the position and orientation of the user's viewpoint. The rotation of the bus is 90 degrees different from the orientation of the user's viewpoint. One of the difficulties in this program is to obtain a correct rotation value for the bus, based on the user's current viewpoint orientation. First we consider the simplest case, namely, the initial situation in which the user looks in the $-Z$ direction and the bus is positioned in the $+X$ direction, as shown in Figure \ref{bus-xz00}. It is easy to see the relation between these two rotations if we have a look at Figure \ref{bus-xz0}: $R3= 1.571$. We want to obtain a general formula to calculate the new bus rotation based on the viewpoint's orientation (i.e. rotation), which is shown in Figure \ref{bus-xz1} and Figure \ref{bus-xz2}. Figure \ref{bus-xz1} shows the situation in which the user turns to the right when navigating. Based on the right-hand system of rotation calculations in VRML, the value of the user's viewpoint orientation is $\langle 0.0, -1.0, 0.0, R2\rangle$. Thus, the bus rotation has to be set to $R3= 1.57-R2$. Figure \ref{bus-xz2} shows the situation in which the user turns to the left. The user's viewpoint orientation is $\langle 0.0, 1.0, 0.0, R2\rangle$. Therefore, $R3$ should be $R2+1.57$. The general formula which can be used to compute the new rotation of the bus based on the user's viewpoint orientation: \[R3 = sign(Y2)*R2 + 1.57.\] where $Y2$ is the Y-value of the user's viewpoint orientation. \begin{figure} \label{bus-xz00} \resizebox*{7.5cm}{!}{\includegraphics{bus-xz00.jpg}} \caption{Initial Situation of Bus Driving} \end{figure} \begin{figure} \label{bus-xz0} \resizebox*{7.5cm}{!}{\includegraphics{bus-xz0.jpg}} \caption{The initial rotation values} \end{figure} \begin{figure} \label{bus-xz1} \resizebox*{7.5cm}{!}{\includegraphics{bus-xz1.jpg}} \caption{User turns to the right} \end{figure} \begin{figure} \label{bus-xz2} \resizebox*{7.5cm}{!}{\includegraphics{bus-xz2.jpg}} \caption{User turns to the left} \end{figure} \subsection{The Vector Library in DLP} In the bus example above, we can see that the calculation of the correct rotation values sometimes becomes a somewhat tricky task. We have to consider different situations to create a general formula which covers all cases for the calculation of the correct rotation value. Some knowledge of 3D graphics mathematics is helpful to solve this kind of problems. DLP offers a vector library ($vectorlib$), which is useful for vector operations, in particular, for rotation calculations. Refer to a 3D graphics textbook for a general background of 3D mathematics. Several typical vectorlib predicates : \begin{itemize} \item $vector\_cross\_product(+vector(X1,Y1,Z1), +vector(X2,Y2,Z2), \\ -vector(X,Y,Z), -R)$ : the vector $\langle X,Y,Z\rangle$, and the angle $R$ are the cross product and the angle of the vector $\langle X1,Y1,Z1\rangle$ and the vector $\langle X2, Y2,Z2\rangle$, (based on the right-handed system). \item $direction\_vector(+position(X1,Y1,Z1),+ position(X2,Y2,Z2),\\ -vector(X,Y,Z)) $: $\langle X, Y, Z\rangle$ is the vector with starting point $\langle X1, Y1,Z1\rangle$ and end point $\langle X2,Y2,Z2\rangle$. \item $vector\_rotation(vector(X1,Y1,Z1), rotation(X,Y,Z,R), \\ vector(X2,Y2,Z2)) $: the resulting vector of a vector $\langle X1,Y1,Z1\rangle$ and a rotation $\langle X,Y,Z,R\rangle$ is $\langle X2,Y2,Z2\rangle$. \item $position\_rotation(position(X1,Y1,Z1), rotation(X,Y,Z,R),\\ position(X2,Y2,Z2))$: the resulting position of a position $\langle X1,Y1,Z1\rangle$ and a rotation $\langle X,Y,Z,R\rangle$ is $\langle X2,Y2,Z2\rangle$. \end{itemize} We can use the $vectorlib$ predicates to compute the intended rotations in the bus example as follows: \begin{verbatim} :-object wasp2v : [bcilib,vectorlib]. var url = './street/street5.wrl'. var timelimit = 300. ...... 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), 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). look_in_direction(Object, InitVector,DesVector):- vector_cross_product(InitVector,DesVector,vector(X,Y,Z),R), setRotation(Object,X,Y,Z,R). :-end_object wasp2v. \end{verbatim} In order to use the vector library, we add the $vectorlib$ to the header of the program object. We define a new predicate $look\_in\_direction$ which sets the object with an initial direction $InitVector$ to a destination direction $DesVector$. We know that the user's initial orientation is oriented to the negative Z direction, namely, $\langle 0,0,-1\rangle$ by default. After $rotation(X2,Y2,Z2,R2)$, the user looks in the direction $vector(X3,Y3,Z3)$, which can be calculated by the predicate $vector\_rotation$ in the vector library. The initial bus orientation is $vector(1,0,0)$. Therefore, during driving, the bus should keep the same orientation as the user by calling the predicate $look\_in\_direction$. \subsection{Ball Kicking} Consider a simple soccer game, in which the user is the only player in the game. If the user gets close enough to the soccer ball, the ball should move to a new position according to the position difference between the player and the ball. In the following program, we set the kickable distance to 2 meter. Namely, if the distance between the user and the ball is smaller than 2 meter, then the ball should be moved to a new position. We calculate a new position of the ball based on the position difference. If the user is at the left side of the ball, then the ball should move to the right; if the user is at the right of the ball, then the ball should move to the left. In the program, we set the move coefficient to 3: if the difference of the x parameter between the user and ball is $Xdif$, then the new position of ball of the x parameter should be increased by $3 Xdif$. The same for the difference of the y parameter. Figure \ref{kick-xz0} shows the relation between the initial position of the ball and the destination position after kicking. \begin{verbatim} :-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(_, _). 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. \end{verbatim} \begin{figure} \label{kick-xz0} \resizebox*{7.5cm}{!}{\includegraphics{kick-xz0.jpg}} \caption{kicking ball to a position} \end{figure} \subsection{Soccer Kicking with Goalkeeper} We can extend the example of ball kicking above by adding a goalkeeper to it, in such a way that the goalkeeper always looks at the ball and can check the position of the ball. If the ball is near the goalkeeper, say, within a distance of 3 meter, then the goalkeeper can move the ball to a new position. We use the vector library for the calculation of the rotation in the predicate $look\_at\_ball$, which simplifies the problem: \begin{verbatim} ...... 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). ...... near_ball_then_kick(Agent, Ball):- ...... setPosition(Ball,X3,Y1,Z3), checkBallPosition(Ball,X3,Y1,Z3). 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 < 3, !, X2 is X - 5, setPosition(Ball,X2,Y,Z). checkBallPosition(_,_,_,_). look_at_ball(Player,Ball):- getPosition(Player,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(Player,vector(0,0,1),vector(X2,Y2,Z2)). ...... \end{verbatim} In the definiton of the predicate $look\_at\_ball$, we first obtain the positions of the player and the ball. We are not interested in the Y-parameters for the calculation of the rotations, because the player should not look down to the ball by rotating the whole body. This should be achieved by rotating the player's head. Based on the two positions, we can calculate the destination orientation of the player which can look at the ball by calling the predicate $direction\_vector$ in the vector library. We know that the initial orientation of an avatar is in the positive Z direction by default. Therefore, looking at the ball can be realized by calling the predicate $look\_in\_direction$. \begin{problems} \prob Variants of the title-moving. \subprob Design a DLP program to implement a rolling text, namely, the text moves in the positive Y-direction. \subprob Design a DLP program to implement moving titles in which the texts and the colors of the titles are changed regularly, using the following facts: \begin{verbatim} title_text(1, 'Intelligent Multimedia Technology', red):-!. title_text(2, 'Moving Title Example', yellow):-!. title_text(3, 'Changing Texts and Colors', green):-!. ...... \end{verbatim} \prob Improve the example of ball kicking so that the soccer ball continuously moves to a new position. It should not simply jump to the new position. \prob 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. \prob 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 does not move if the engine stops. \end{problems}