📄 427-432.html
字号:
<HTML>
<HEAD>
<META name=vsisbn content="1571690433"><META name=vstitle content="Black Art of Java Game Programming"><META name=vsauthor content="Joel Fan"><META name=vsimprint content="Sams"><META name=vspublisher content="Macmillan Computer Publishing"><META name=vspubdate content="11/01/96"><META name=vscategory content="Web and Software Development: Programming, Scripting, and Markup Languages: Java"><TITLE>Black Art of Java Game Programming:Into the Third Dimension</TITLE>
<!-- HEADER --><STYLE type="text/css"> <!-- A:hover { color : Red; } --></STYLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><script><!--function displayWindow(url, width, height) { var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes'); if (Win) { Win.focus(); }}//--></script><SCRIPT><!--function popUp(url) { var Win = window.open(url,"displayWindow",'width=400,height=300,resizable=1,scrollbars=yes'); if (Win) { Win.focus(); }}//--></SCRIPT><script language="JavaScript1.2"><!--function checkForQuery(fm) { /* get the query value */ var i = escape(fm.query.value); if (i == "") { alert('Please enter a search word or phrase'); return false; } /* query is blank, dont run the .jsp file */ else return true; /* execute the .jsp file */}//--></script></HEAD><BODY>
<TABLE border=0 cellspacing=0 cellpadding=0>
<tr>
<td width=75 valign=top>
<img src="../1571690433.gif" width=60 height=73 alt="Black Art of Java Game Programming" border="1">
</td>
<td align="left">
<font face="arial, helvetica" size="-1" color="#336633"><b>Black Art of Java Game Programming</b></font>
<br>
<font face="arial, helvetica" size="-1"><i>by Joel Fan</i>
<br>
Sams, Macmillan Computer Publishing
<br>
<b>ISBN:</b> 1571690433<b> Pub Date:</b> 11/01/96</font>
</td>
</tr>
</table>
<P>
<!--ISBN=1571690433//-->
<!--TITLE=Black Art of Java Game Programming//-->
<!--AUTHOR=Joel Fan//-->
<!--AUTHOR=Eric Ries//-->
<!--AUTHOR=Calin Tenitchi//-->
<!--PUBLISHER=Macmillan Computer Publishing//-->
<!--IMPRINT=Sams//-->
<!--CHAPTER=11//-->
<!--PAGES=427-432//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="424-427.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="433-434.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading44"></A><FONT COLOR="#000077">Implementing the 3D Angle Class (fAngle3d)</FONT></H4>
<P>The fAngle3d class, shown in Listing 11-10, simplifies the handling of 3D angles. The x, y, z values contain the angle of rotation about the principal axes.
</P>
<P><B>Listing 11-10</B> The fAngle3d class</P>
<!-- CODE //-->
<PRE>
public class fAngle3d{
double x;
double y;
double z;
fAngle3d (double x0, double y0, double z0) {
x=x0; y=y0; z=z0;
}
fAngle3d () {
x=y=z=0;
}
fAngle3d (fAngle3d a) {
x=a.x; y=a.y; z=a.z;
}
boolean equals (fAngle3d a) {
return (a.x==x)&&(a.y==y)&&(a.z==z);
}
void set (fAngle3d a) {
x=a.x; y=a.y; z=a.z;
}
}
</PRE>
<!-- END CODE //-->
<H4 ALIGN="LEFT"><A NAME="Heading45"></A><FONT COLOR="#000077">Implementing the 3D Matrix Class (fMatrix3d)</FONT></H4>
<P>The generic 3D matrix, fGeneric3dMatrix, from Appendix E, 3D Transforms, only contains the basic transforms such as scaling, rotation, and translation. The extension of the generic matrix, fMatrix3d, shown in Listing 11-11, simply “hides” the actual series of transforms by introducing new methods.
</P>
<P><B>Listing 11-11</B> The fMatrix3d class</P>
<!-- CODE //-->
<PRE>
/**
* A 3d matrix that hides the making of the different
* transforms
*/
class fMatrix3d extends fGeneric3dMatrix {
/**
* construct the matrix
*/
public fMatrix3d(){
super();
}
/**
* let matrix contain the MCS to WCS transform
*/
public void makeMCStoWCStransform(fPoint3d pos,fAngle3d agl,fPoint3d
scale){
makeIdentity();
concatS(scale.x,scale.y,scale.z);
concatRx(agl.x);
concatRy(agl.y);
concatRz(agl.z);
concatT(pos.x,pos.y,pos.z);
}
/**
* let matrix contain the MCS to WCS transform, without scaling
*/
public void makeMCStoWCStransform(fPoint3d pos,fAngle3d agl){
makeIdentity();
concatRx(agl.x);
concatRy(agl.y);
concatRz(agl.z);
concatT(pos.x,pos.y,pos.z);
}
/**
* let matrix contain the WCS to MCS transform
*/
public void makeWCStoVCStransform(fPoint3d pos,fAngle3d agl){
makeIdentity();
concatT(-pos.x,-pos.y,-pos.z);
concatRz(-agl.z);
concatRy(-agl.y);
concatRx(-agl.x);
}
}
</PRE>
<!-- END CODE //-->
<H3><A NAME="Heading46"></A><FONT COLOR="#000077">The Complete Chain of Transforms</FONT></H3>
<P>In the previous section we looked at the 3D pipeline that transforms a set of vertices all the way from MCS to SCS. Let’s summarize the results with Figure 11-22.
</P>
<P><A NAME="Fig24"></A><A HREF="javascript:displayWindow('images/11-24.jpg',249,66 )"><IMG SRC="images/11-24t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/11-24.jpg',249,66)"><FONT COLOR="#000077"><B>Figure 11-22</B></FONT></A> The chain of transforms</P>
<P>We now have quite a few classes (and we are not done yet), so let’s look at how the chain in Figure 11-22 works.
</P>
<DL>
<DD><B>1.</B> The vertices of a polyhedron are transformed from MCS to WCS.
<DD><B>2.</B> The transformed vertices are fed to a camera (fCamera).
<DD><B>3.</B> The camera transforms the vertices from WCS to VCS, simplifying the projection stage.
<DD><B>4.</B> The vertices are projected from VCS to SCS.
<DD><B>5.</B> The screen coordinates are returned and used as arguments to the polyhedron’s paint() method.
<DD><B>6.</B> The fIndexingPolygons are instructed to paint themselves using the two-dimensional coordinates supplied by the camera.
<DD><B>7.</B> The scratch-pad polygon is used as a hook to Java’s API, and the polygons are rendered.
</DL>
<H3><A NAME="Heading47"></A><FONT COLOR="#000077">The Polyhedron Instance Class</FONT></H3>
<P>As you might have noticed, there is a missing link in the chain. Nowhere have we mentioned how the vertices of a polyhedron are transformed from MCS to WCS. This issue was saved until last because it can be solved in a number of ways that may all seem equally good at first glance. What we need is to somehow specify the position and orientation of a polyhedron in the WCS. One solution would be to extend the fPolyhedron<B> </B>and add these features to it. But think about the following scenario.</P>
<P>We want to model a city made of hundreds of buildings. Half of them are identical in that they use the exact same 3D model. This would mean that we would waste memory storing the same model vertices over and over again as in Figure 11-23.</P>
<P><A NAME="Fig25"></A><A HREF="javascript:displayWindow('images/11-25.jpg',233,70 )"><IMG SRC="images/11-25t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/11-25.jpg',233,70)"><FONT COLOR="#000077"><B>Figure 11-23</B></FONT></A> Same vertices stored in several instances of a extension of fPolyhedron</P>
<P>Another solution would be to not store the world coordinates at all. This can be solved with a matrix multiplication, as in Appendix E. On the other hand, buildings are pretty much static. They don’t move around unless there is an earthquake. Recalculating the vertices of a static object from MCS to WCS every time the object needs to be rendered seems like a waste of calculations. Even dynamic objects that change their world coordinates a lot, such as cars, stand still most of the time, whether they are in garages or traffic.
</P>
<P>A good solution would be to have a class that is an <I>instance</I> of a polyhedron. The easiest way of understanding this is to look at Figure 11-24.</P>
<P><A NAME="Fig26"></A><A HREF="javascript:displayWindow('images/11-26.jpg',405,149 )"><IMG SRC="images/11-26t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/11-26.jpg',405,149)"><FONT COLOR="#000077"><B>Figure 11-24</B></FONT></A> A polyhedron instance using a polyhedron as a model</P>
<P>In this arrangement, a polyhedron instance contains the vertices transformed to WCS but doesn’t contain a copy of the model vertices. This kind of structure would cut the memory use almost by half. It is also a good optimization, since it avoids redundant MCS to WCS transforms. There are also other factors that we should consider. Many objects are very short-lived. For example, a missile only lives a couple of seconds, but the overhead of constructing it is the same as for a never-dying mountain. This means that we must try minimizing the overhead of constructing new instances of a polyhedron. Using this class structure, the model coordinates don’t have to be copied to every instance. But there are also disadvantages to this approach. An instance of a polyhedron cannot change its model coordinates, since doing so would have an impact on all instances using the same model. This problem can be solved by assigning a personal polyhedron by simply cloning it before any changes are made to the model vertices.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="424-427.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="433-434.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -