[nexuiz-commits] r8727 - in trunk/data/qcsrc: server warpzonelib

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Feb 28 14:46:16 EST 2010


Author: div0
Date: 2010-02-28 14:46:15 -0500 (Sun, 28 Feb 2010)
New Revision: 8727

Modified:
   trunk/data/qcsrc/server/extensions.qh
   trunk/data/qcsrc/warpzonelib/server.qc
Log:
provide two alternatives to triger_warpzone--killtarget-->target_position:
1. trigger_warpzone_position--target-->trigger_warpzone
2. none, and using a a face with textures/common/warpzone shader instead: its normal is vectoangles'd into an orientation, and its center of weight is used as origin

Modified: trunk/data/qcsrc/server/extensions.qh
===================================================================
--- trunk/data/qcsrc/server/extensions.qh	2010-02-28 19:46:10 UTC (rev 8726)
+++ trunk/data/qcsrc/server/extensions.qh	2010-02-28 19:46:15 UTC (rev 8727)
@@ -806,10 +806,18 @@
 float SPA_LIGHTMAP0_COLOR = 6;
 //builtin definitions:
 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
-
 //description:
 //function to query extended information about a point on a certain surface
 
+//DP_QC_GETSURFACETRIANGLE
+//idea: div0
+//darkplaces implementation: div0
+//builtin definitions:
+float(entity e, float s) getsurfacenumtriangles = #628;
+vector(entity e, float s, float n) getsurfacetriangle = #629;
+//description:
+//function to query triangles of a surface
+
 //DP_QC_GETTAGINFO
 //idea: VorteX, LordHavoc (somebody else?)
 //DarkPlaces implementation: VorteX

Modified: trunk/data/qcsrc/warpzonelib/server.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/server.qc	2010-02-28 19:46:10 UTC (rev 8726)
+++ trunk/data/qcsrc/warpzonelib/server.qc	2010-02-28 19:46:15 UTC (rev 8727)
@@ -40,7 +40,7 @@
 	v0 = player.velocity;
 	a0 = player.angles;
 
-	if(WarpZone_PlaneDist(self, o0) >= 0) // wrong side of the portal
+	if(WarpZone_PlaneDist(self, o0) >= 0) // wrong side of the trigger_warpzone
 		return 2;
 	// no failure, we simply don't want to teleport yet; TODO in
 	// this situation we may want to create a temporary clone
@@ -274,15 +274,96 @@
 
 void WarpZone_InitStep_UpdateTransform()
 {
-	if(!self.enemy || self.enemy.enemy != self || !self.aiment)
+	vector org, ang, norm, point;
+	float area;
+	vector tri, a, b, c, p, q, n;
+	float i_s, i_t, n_t;
+	string tex;
+
+	if(!self.enemy || self.enemy.enemy != self)
 	{
 		error("Invalid warp zone detected. Killed.");
 		return;
 	}
 
-	WarpZone_SetUp(self, self.aiment.origin, self.aiment.angles, self.enemy.aiment.origin, self.enemy.aiment.angles);
+	org = self.origin;
+	if(org == '0 0 0')
+		org = 0.5 * (self.mins + self.maxs);
 
-	// now enable touch
+	norm = point = '0 0 0';
+	area = 0;
+	for(i_s = 0; ; ++i_s)
+	{
+		tex = getsurfacetexture(self, i_s);
+		if not(tex)
+			break; // this is beyond the last one
+		if(tex != "textures/common/warpzone")
+			continue;
+		n_t = getsurfacenumtriangles(self, i_s);
+		for(i_t = 0; i_t < n_t; ++i_t)
+		{
+			tri = getsurfacetriangle(self, i_s, i_t);
+			a = getsurfacepoint(self, i_s, tri_x);
+			b = getsurfacepoint(self, i_s, tri_y);
+			c = getsurfacepoint(self, i_s, tri_z);
+			p = b - a;
+			q = c - a;
+			n =     '1 0 0' * (q_y * p_z - q_z * p_y)
+			+       '0 1 0' * (q_z * p_x - q_x * p_z)
+			+       '0 0 1' * (q_x * p_y - q_y * p_x);
+			area = area + vlen(n);
+			norm = norm + n;
+			point = point + vlen(n) * (a + b + c);
+		}
+	}
+	if(area > 0)
+	{
+		norm = norm * (1 / area);
+		point = point * (1 / (3 * area));
+		if(vlen(norm) < 0.99)
+		{
+			print("trigger_warpzone near ", vtos(self.aiment.origin), " is nonplanar. BEWARE.\n");
+			area = 0; // no autofixing in this case
+		}
+		norm = normalize(norm);
+	}
+
+	if(self.aiment)
+	{
+		org = self.aiment.origin;
+		ang = self.aiment.angles;
+		if(area > 0)
+		{
+			org = org - ((org - point) * norm) * norm; // project to plane
+			makevectors(ang);
+			if(norm * v_forward < 0)
+			{
+				print("Position target of trigger_warpzone near ", vtos(self.aiment.origin), " points into trigger_warpzone. BEWARE.\n");
+				norm = -1 * norm;
+			}
+			ang = vectoangles(norm, v_up); // keep rotation, but turn exactly against plane
+			ang_x = -ang_x;
+			if(norm * v_forward < 0.99)
+				print("trigger_warpzone near ", vtos(self.aiment.origin), " has been turned to match plane orientation (", vtos(self.aiment.angles), " -> ", vtos(ang), "\n");
+			if(vlen(org - self.aiment.origin) > 0.5)
+				print("trigger_warpzone near ", vtos(self.aiment.origin), " has been moved to match the plane (", vtos(self.aiment.origin), " -> ", vtos(org), ").\n");
+		}
+	}
+	else if(area > 0)
+	{
+		org = point;
+		ang = vectoangles(norm);
+		ang_x = -ang_x;
+	}
+	else
+		error("cannot infer origin/angles for this warpzone, please use a killtarget or a trigger_warpzone_position");
+
+	self.warpzone_origin = org;
+	self.warpzone_angles = ang;
+}
+void WarpZone_InitStep_FinalizeTransform()
+{
+	WarpZone_SetUp(self, self.warpzone_origin, self.warpzone_angles, self.enemy.warpzone_origin, self.enemy.warpzone_angles);
 	self.touch = WarpZone_Touch;
 }
 
@@ -329,6 +410,8 @@
 			WarpZonePosition_InitStep_FindTarget();
 		for(self = warpzone_first; self; self = self.warpzone_next)
 			WarpZone_InitStep_UpdateTransform();
+		for(self = warpzone_first; self; self = self.warpzone_next)
+			WarpZone_InitStep_FinalizeTransform();
 		self = e;
 	}
 	for(e = world; (e = nextent(e)); )



More information about the nexuiz-commits mailing list