[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