1997Q3/
<!-- MHonArc v2.4.4 -->
<!--X-Subject: Re: [MUD&#45;Dev]  Finding Space -->
<!--X-From-R13: [vpunry Vburafrr <zvpunryNfcnegn.znvafgernz.arg> -->
<!--X-Date: Mon, 18 Aug 1997 19:22:13 +0000 -->
<!--X-Message-Id: 33F8A056.2330852C#sparta,mainstream.net -->
<!--X-Content-Type: text/plain -->
<!--X-Reference: Pine.GSO.3.95q.970817213842.16831B&#45;100000@uhunix2 -->
<!--X-Head-End-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>MUD-Dev message, Re: [MUD-Dev]  Finding Space</title>
<!-- meta name="robots" content="noindex,nofollow" -->
<link rev="made" href="mailto:michael#sparta,mainstream.net">
</head>
<body background="/backgrounds/paperback.gif" bgcolor="#ffffff"
      text="#000000" link="#0000FF" alink="#FF0000" vlink="#006000">

  <font size="+4" color="#804040">
    <strong><em>MUD-Dev<br>mailing list archive</em></strong>
  </font>
      
<br>
[&nbsp;<a href="../">Other Periods</a>
&nbsp;|&nbsp;<a href="../../">Other mailing lists</a>
&nbsp;|&nbsp;<a href="/search.php3">Search</a>
&nbsp;]
<br clear=all><hr>
<!--X-Body-Begin-->
<!--X-User-Header-->
<!--X-User-Header-End-->
<!--X-TopPNI-->

Date:&nbsp;
[&nbsp;<a href="msg00655.html">Previous</a>
&nbsp;|&nbsp;<a href="msg00657.html">Next</a>
&nbsp;]
&nbsp;&nbsp;&nbsp;&nbsp;
Thread:&nbsp;
[&nbsp;<a href="msg00653.html">Previous</a>
&nbsp;|&nbsp;<a href="msg00657.html">Next</a>
&nbsp;]
&nbsp;&nbsp;&nbsp;&nbsp;
Index:&nbsp;
[&nbsp;<A HREF="author.html#00656">Author</A>
&nbsp;|&nbsp;<A HREF="#00656">Date</A>
&nbsp;|&nbsp;<A HREF="thread.html#00656">Thread</A>
&nbsp;]

<!--X-TopPNI-End-->
<!--X-MsgBody-->
<!--X-Subject-Header-Begin-->
<H1>Re: [MUD-Dev]  Finding Space</H1>
<HR>
<!--X-Subject-Header-End-->
<!--X-Head-of-Message-->
<UL>
<LI><em>To</em>: <A HREF="mailto:mud-dev#null,net">mud-dev#null,net</A></LI>
<LI><em>Subject</em>: Re: [MUD-Dev]  Finding Space</LI>
<LI><em>From</em>: Michael Hohensee &lt;<A HREF="mailto:michael#sparta,mainstream.net">michael#sparta,mainstream.net</A>&gt;</LI>
<LI><em>Date</em>: Mon, 18 Aug 1997 15:19:51 -0400</LI>
<LI><em>CC</em>: <A HREF="mailto:michael#sparta,mainstream.net">michael#sparta,mainstream.net</A></LI>
<LI><em>Sender</em>: <A HREF="mailto:michael#sparta,mainstream.net">michael#sparta,mainstream.net</A></LI>
</UL>
<!--X-Head-of-Message-End-->
<!--X-Head-Body-Sep-Begin-->
<HR>
<!--X-Head-Body-Sep-End-->
<!--X-Body-of-Message-->
<PRE>
Ok, I should mention that I finally do have a working collision 
detection and space finding system written, even though it 
isn't the most efficent in the world (it is a grinder.. ;).
I'll post it at the bottom of this message, for those who are 
interested.

Nathan Yospe wrote:
&gt; 
&gt; On Fri, 15 Aug 1997, Michael Hohensee wrote:
&gt; 
&gt; :I've been working up a system in which objects take up space in a
&gt; :co-ordinate based world, and I seem to have hit a stumbling block.  I
&gt; :know that others have probably solved this problem (Physmud++ *must*
&gt; :have had to solve this ;), so maybe someone can help me.
&gt; 
&gt; Yes and no. Same as collision detection... exactly the same, in fact, as
&gt; this is a big part of what I consider collision detection. I use spheres
&gt; around the center of volume (not to be confused with the center of mass)
&gt; of a group of objects, single composite object, individual components...
&gt; and then I assume that the particulate (smallest tracked) components are
&gt; spherical. This reduces any "will I fit?" problem to a series of fast
&gt; comparisons that only get ugly when a collision is immenent (and since I
&gt; track in four dimensions, the fourth being a minute projection forward in
&gt; time, I have a chance to prepare for collisions.)
&gt; 
&gt; :Here's how it works:
&gt; 
&gt; :We are representing a three dimensional space, but in this example we'll
&gt; :restrict it to two dimensions.
&gt; 
&gt; :4-----------------------------
&gt; :3------******--------**-------
&gt; :2------******-----**-**--*****
&gt; :1----*-******-----**-**-------
&gt; :0-----------------------------
&gt; : 0 2 4 6 8 1012
&gt; :  1 3 5 7 9 11
&gt; :'-' = empty space, '*' = space taken up by an object.
&gt; 
&gt; :For simplicity, all objects take up a cubical volume of space (square,
&gt; :in this case).  Objects are held in a tree or linked list of structs
&gt; :which contain the origin point of the object, and the dimensions of the
&gt; :object.  For example, the big square in the picture above would be
&gt; :Location=6,1 -- Dimensions=6,3.
&gt; 
&gt; First off, spheres are simpler in 3D than cubes. Little bit of advice from
&gt; a graphical engine hand. MUCH simpler.
&gt; 
&gt; :I can store anything to any location I want, but I want to avoid
&gt; :overlapping objects onto each other (it's bad), so I need to be able to
&gt; :find empty space between objects.  I can't just try to place an object
&gt; :in every location, since there isn't any granularity to this space (I
&gt; :use floats instead of ints).
&gt; 
&gt; And thus the reason for spheres. Use a transform and a single calculation
&gt; gives you the shortest distance between two points. Then just check to
&gt; make sure that's more than the radius of both spheres summed.

Yes, spheres would be a *lot* more resource-friendly, but the problem 
I have with spheres is that they aren't very good at tiling space, since
there are always little gaps between spheres.

I might be able to get around this by differentiating between the world 
and the objects within it, (world is a cubical construct, objects are 
spheres) but this runs counter to my mud-coding philosophy, which states
that every component of the world should be able to generally behave
like
any other component. (objects can hold worlds of various flavors). 
Putting
a square inside a circle would probably just drive players (and me)
nuts.
:)

I suppose you could overlap some spheres and get full coverage, but how 
do you decide which sphere an object is actually in?

Here's my "solution" I promised you.  Note that it is written
for a linked-list implementation of a container.  Depending
upon the number of objects it contains, I plan to have it
switch to a more efficient container list. (good old separation
of implementation from interface.)

struct LL_Holder {
  A_Obj *holding;
  Location *loc;
};

struct Location {
  double X;
  double Y;
  double Z;
};

struct Dimensions {
  double Xwidth;
  double Ywidth;
  double Zwidth;
};

class LL_Container : A_Container {

  bool does_overlap(A_Obj *obj, Location *loc)
  {
    LL_Holder *ptr;
    double  X,  Y,  Z,  pX,  pY,  pZ;
    double oX, oY, oZ, opX, opY, opZ;

    X = loc-&gt;X;
    Y = loc-&gt;Y;
    Z = loc-&gt;Z;
    pX= obj-&gt;my_dimensions-&gt;Xwidth;
    pY= obj-&gt;my_dimensions-&gt;Ywidth;
    pZ= obj-&gt;my_dimensions-&gt;Zwidth;


    for (ptr = held; ptr != 0; ptr = ptr-&gt;next)
      {
	oX = ptr-&gt;loc-&gt;X;
	oY = ptr-&gt;loc-&gt;Y;
	oZ = ptr-&gt;loc-&gt;Z;
	opX= ptr-&gt;holding-&gt;my_dimensions-&gt;Xwidth;
	opY= ptr-&gt;holding-&gt;my_dimensions-&gt;Ywidth;
	opZ= ptr-&gt;holding-&gt;my_dimensions-&gt;Zwidth;
	
	/* Somewhat hard to read..  I check for
	   linear overlap in each dimension.
	   To visualize this, draw two cubes, and label
	   their origins (X,Y,Z) , and (oX,oY,oZ).
	   Label the corner directly opposite the
	   origins of the cubes (pX,pY,pZ) and (opX,opY,opZ)
	   respectively.  Then label the other corners
   	   appropiately. */

	if ( ((oX &lt;= X) &amp;&amp; (oX + opX &gt;= X + pX)) ||
	     ((oX &gt; X) &amp;&amp; ( (oX &lt; X + pX) || 
			    (oX + opX &lt; X + pX) )) )
	  if ( ((oY &lt;= Y) &amp;&amp; (oY + opY &gt;= Y + pY)) ||
	       ((oY &gt; Y) &amp;&amp; ( (oY &lt; Y + pY) || 
			      (oY + opY &lt; Y + pY) )) )
	    if ( ((oZ &lt;= Z) &amp;&amp; (oZ + opZ &gt;= Z + pZ)) ||
		 ((oZ &gt; Z) &amp;&amp; ( (oZ &lt; Z + pZ) || 
				(oZ + opZ &lt; Z + pZ) )) )
	      return 1;
      }
    return 0;
  }

  bool find_space(A_Obj *for_me, Location *loc) 
  {
    LL_Holder *ptr;
    Location try, *a_loc = &amp;try;
    double x, y, z;
    double xp, yp, zp;

    a_loc-&gt;X = 0.0;
    a_loc-&gt;Y = 0.0;
    a_loc-&gt;Z = 0.0;

    if (!does_overlap(for_me, a_loc))
      {
	loc-&gt;X = a_loc-&gt;X;
	loc-&gt;Y = a_loc-&gt;Y;
	loc-&gt;Z = a_loc-&gt;Z;
	return 1;
      }

    for (ptr = held; ptr != 0; ptr = ptr-&gt;next)
      {
	x = ptr-&gt;loc-&gt;X;
	y = ptr-&gt;loc-&gt;Y;
	z = ptr-&gt;loc-&gt;Z;
	xp = ptr-&gt;holding-&gt;my_dimensions-&gt;Xwidth;
	yp = ptr-&gt;holding-&gt;my_dimensions-&gt;Ywidth;
	zp = ptr-&gt;holding-&gt;my_dimensions-&gt;Zwidth;

	a_loc-&gt;X = x;
	a_loc-&gt;Y = y;
	a_loc-&gt;Z = z;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;X += xp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;X -= xp;
	a_loc-&gt;Y += yp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;Y -= yp;
	a_loc-&gt;Z += zp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;Y += yp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;Y -= yp;
	a_loc-&gt;X += xp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;Z -= zp;
	a_loc-&gt;Y += yp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }

	a_loc-&gt;Z += zp;
	if (!does_overlap(for_me, a_loc))
	  {
	    loc-&gt;X = a_loc-&gt;X;
	    loc-&gt;Y = a_loc-&gt;Y;
	    loc-&gt;Z = a_loc-&gt;Z;
	    return 1;
	  }
      }
    return 0;
  }
};

-- 
Michael Hohensee       michael#sparta,mainstream.net
<A  HREF="http://www.geocities.com/SiliconValley/Heights/9025/">http://www.geocities.com/SiliconValley/Heights/9025/</A>
      Finger me for my PGP Public Key, or use: 
<A  HREF="http://sparta.mainstream.net/michael/pgpkey.txt">http://sparta.mainstream.net/michael/pgpkey.txt</A>

</PRE>

<!--X-Body-of-Message-End-->
<!--X-MsgBody-End-->
<!--X-Follow-Ups-->
<HR>
<!--X-Follow-Ups-End-->
<!--X-References-->
<UL><LI><STRONG>References</STRONG>:
<UL>
<LI><STRONG><A NAME="00653" HREF="msg00653.html">Re: [MUD-Dev]  Finding Space</A></STRONG>
<UL><LI><EM>From:</EM> Nathan Yospe &lt;yospe#hawaii,edu&gt;</LI></UL></LI>
</UL></LI></UL>
<!--X-References-End-->
<!--X-BotPNI-->
<UL>
<LI>Prev by Date:
<STRONG><A HREF="msg00655.html">Re: [MUD-Dev]  Character evolution</A></STRONG>
</LI>
<LI>Next by Date:
<STRONG><A HREF="msg00657.html">Re: [MUD-Dev]  Finding Space</A></STRONG>
</LI>
<LI>Prev by thread:
<STRONG><A HREF="msg00653.html">Re: [MUD-Dev]  Finding Space</A></STRONG>
</LI>
<LI>Next by thread:
<STRONG><A HREF="msg00657.html">Re: [MUD-Dev]  Finding Space</A></STRONG>
</LI>
<LI>Index(es):
<UL>
<LI><A HREF="index.html#00656"><STRONG>Date</STRONG></A></LI>
<LI><A HREF="thread.html#00656"><STRONG>Thread</STRONG></A></LI>
</UL>
</LI>
</UL>

<!--X-BotPNI-End-->
<!--X-User-Footer-->
<!--X-User-Footer-End-->
<ul><li>Thread context:
<BLOCKQUOTE><UL>
<LI><strong><A NAME="00603" HREF="msg00603.html">Finding Space</A></strong>, 
Michael Hohensee <a href="mailto:michael#sparta,mainstream.net">michael#sparta,mainstream.net</a>, Fri 15 Aug 1997, 14:03 GMT
<UL>
<LI><strong><A NAME="00607" HREF="msg00607.html">Re: [MUD-Dev]  Finding Space</A></strong>, 
Shawn Halpenny <a href="mailto:malachai#iname,com">malachai#iname,com</a>, Fri 15 Aug 1997, 18:12 GMT
<UL>
<LI><strong><A NAME="00654" HREF="msg00654.html">Re: [MUD-Dev]  Finding Space</A></strong>, 
Nathan Yospe <a href="mailto:yospe#hawaii,edu">yospe#hawaii,edu</a>, Mon 18 Aug 1997, 08:01 GMT
</LI>
</UL>
</LI>
<LI><strong><A NAME="00653" HREF="msg00653.html">Re: [MUD-Dev]  Finding Space</A></strong>, 
Nathan Yospe <a href="mailto:yospe#hawaii,edu">yospe#hawaii,edu</a>, Mon 18 Aug 1997, 07:48 GMT
<UL>
<LI><strong><A NAME="00656" HREF="msg00656.html">Re: [MUD-Dev]  Finding Space</A></strong>, 
Michael Hohensee <a href="mailto:michael#sparta,mainstream.net">michael#sparta,mainstream.net</a>, Mon 18 Aug 1997, 19:22 GMT
</LI>
</UL>
</LI>
<LI><strong><A NAME="00657" HREF="msg00657.html">Re: [MUD-Dev]  Finding Space</A></strong>, 
clawrenc <a href="mailto:clawrenc#cup,hp.com">clawrenc#cup,hp.com</a>, Tue 19 Aug 1997, 00:21 GMT
</LI>
</UL>
</LI>
<LI><strong><A NAME="00556" HREF="msg00556.html">[MUD-Dev]  Spellcaster, or Waving Hands</A></strong>, 
Cynbe ru Taren <a href="mailto:cynbe#laurel,actlab.utexas.edu">cynbe#laurel,actlab.utexas.edu</a>, Thu 14 Aug 1997, 17:50 GMT
<UL>
<LI><strong><A NAME="00583" HREF="msg00583.html">Re: [MUD-Dev]  Spellcaster, or Waving Hands</A></strong>, 
clawrenc <a href="mailto:clawrenc#cup,hp.com">clawrenc#cup,hp.com</a>, Thu 14 Aug 1997, 22:21 GMT
<UL>
<LI><strong><A NAME="00587" HREF="msg00587.html">Re: [MUD-Dev]  Spellcaster, or Waving Hands</A></strong>, 
Richard Woolcock <a href="mailto:KaVir#dial,pipex.com">KaVir#dial,pipex.com</a>, Thu 14 Aug 1997, 23:06 GMT
</LI>
</UL>
</LI>
</UL>
</LI>
</UL></BLOCKQUOTE>

</ul>
<hr>
<center>
[&nbsp;<a href="../">Other Periods</a>
&nbsp;|&nbsp;<a href="../../">Other mailing lists</a>
&nbsp;|&nbsp;<a href="/search.php3">Search</a>
&nbsp;]
</center>
<hr>
</body>
</html>