Re: Point inclusion, Zone points generation, and Zone drawing
Quote:
Originally Posted by Peace-Maker
(Post 2022498)
PHP Code:
if(point[0][i]>=playerPos[i] == point[7][i]>=playerPos[i])
That doesn't look right to me?
|
yeah, that's weird, but right.
Code:
(point[0][i]>=playerPos[i]) == (point[7][i]>=playerPos[i])
if the condition is true for both, then the player(or, better saying, the point) can't be inside the zone.
i tried to do some things. i'm not really sure if it works, i barely tested it with some barrels at dust2.
also, i'm not sure if it's the best way to do that things. i didn't really know how to do that, so i did some terrible drafts on photoshop and it seemed far away that it would be possible to be done. anyways, it's probably a bad method for calculating these things. i wonder how people do it out there in real life.
Code:
#include <sourcemod>
#include <cstrike>
#include <sdktools>
#include <smlib>
#include <sdkhooks>
#pragma semicolon 1
new const Float:NULLBOXPOINTS[8][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
new const Float:ZERO_VECTOR[3] = {0.0, 0.0, 0.0};
Float:setupentitysphere(ent, const Float:addmin[3], const Float:addmax[3], Float:origin[3]){
decl Float:min[3], Float:max[3];
Entity_GetMinSize(ent, min);
AddVectors(min, addmin, min);
Entity_GetMaxSize(ent, max);
AddVectors(max, addmax, max);
Entity_GetAbsOrigin(ent, origin);
decl Float:vec[3];
SubtractVectors(max, min, vec);
ScaleVector(vec, 0.5);
AddVectors(origin, min, origin);
AddVectors(origin, vec, origin);
return SquareRoot(GetVectorDotProduct(vec, vec));
}
bool:collidespheres(const Float:origin1[3], const Float:radius1, const Float:origin2[3], const Float:radius2){
if(GetVectorDistance(origin1, origin2) <= radius1+radius2){
return true;
}else{
return false;
}
}
makeortonormalbase(const Float:points[8][3], Float:base[3][3], Float:bounds[3]){
SubtractVectors(points[1], points[0], base[0]);
SubtractVectors(points[2], points[0], base[1]);
SubtractVectors(points[4], points[0], base[2]);
new Float:norma = SquareRoot(GetVectorDotProduct(base[0], base[0]));
bounds[0] = norma;
ScaleVector(base[0], 1/norma);
norma = SquareRoot(GetVectorDotProduct(base[1], base[1]));
bounds[1] = norma;
ScaleVector(base[1], 1/norma);
norma = SquareRoot(GetVectorDotProduct(base[2], base[2]));
bounds[2] = norma;
ScaleVector(base[2], 1/norma);
}
bool:arepointsinsidebox(const Float:points1[8][3], const Float:base[3][3], const Float:length[3], const Float:points2[8][3]){
for(new i = 0; i < 7; i++){
decl Float:vec[3];
copyvector(points2[i], vec);
SubtractVectors(vec, points1[0], vec);
if(ispointinsidebox(base, length, vec)){
return true;
}else{
continue;
}
}
return false;
}
bool:ispointinsidebox(const Float:base[3][3], const Float:length[3], const Float:point[3]){
for(new i = 0; i < 3; i++){
new Float:thedotproduct = GetVectorDotProduct(point, base[i]);
if(thedotproduct > length[i] || thedotproduct < 0.0){
return false;
}
}
return true;
}
intersectboxes(const Float:points1[8][3], const Float:points2[8][3]){
decl Float:ortonormalbase1[3][3];
decl Float:bounds1[3];
makeortonormalbase(points1, ortonormalbase1, bounds1);
decl Float:ortonormalbase2[3][3];
decl Float:bounds2[3];
makeortonormalbase(points2, ortonormalbase2, bounds2);
if(arepointsinsidebox(points1, ortonormalbase1, bounds1, points2) || arepointsinsidebox(points2, ortonormalbase2, bounds2, points1)){
return true;
}else if(intersectplanewithbox(points1[0], points1[1], points1[2], points2) ||
intersectplanewithbox(points1[1], points1[3], points1[5], points2) ||
intersectplanewithbox(points1[5], points1[4], points1[7], points2) ||
intersectplanewithbox(points1[6], points1[7], points1[2], points2) ||
intersectplanewithbox(points1[6], points1[2], points1[4], points2) ||
intersectplanewithbox(points1[5], points1[1], points1[4], points2)){
return true;
}else{
return false;
}
}
intersectplanewithbox(const Float:point1[3], const Float:point2[3], const Float:point3[3], const Float:box[8][3]){
if(intersectplaneandline(point1, point2, point3, box[0], box[1]) ||
intersectplaneandline(point1, point2, point3, box[0], box[2]) ||
intersectplaneandline(point1, point2, point3, box[2], box[3]) ||
intersectplaneandline(point1, point2, point3, box[1], box[3]) ||
intersectplaneandline(point1, point2, point3, box[0], box[4]) ||
intersectplaneandline(point1, point2, point3, box[1], box[5]) ||
intersectplaneandline(point1, point2, point3, box[2], box[6]) ||
intersectplaneandline(point1, point2, point3, box[3], box[7]) ||
intersectplaneandline(point1, point2, point3, box[4], box[5]) ||
intersectplaneandline(point1, point2, point3, box[4], box[6]) ||
intersectplaneandline(point1, point2, point3, box[6], box[7]) ||
intersectplaneandline(point1, point2, point3, box[5], box[7])){
return true;
}else{
return false;
}
}
setupentityzone(ent, bool:shoulddraw = false, const Float:addmin[3] = ZERO_VECTOR, const Float:addmax[3] = ZERO_VECTOR, Float:points[8][3] = NULLBOXPOINTS){
decl Float:min[3], Float:max[3];
decl Float:angles[3], Float:origin[3];
Entity_GetMinSize(ent, min);
AddVectors(min, addmin, min);
Entity_GetMaxSize(ent, max);
AddVectors(max, addmax, max);
Entity_GetAbsAngles(ent, angles);
Entity_GetAbsOrigin(ent, origin);
for(new i = 0; i < 3; i++){
angles[i] = DegToRad(angles[i]);
}
CreateZonePoints(origin, min, max, angles, points);
if(shoulddraw){
DrawZone(0, points, bsprite, hsprite, {255, 0, 0, 255}, 3.0);
}
}
bool:intersectplaneandline(const Float:plane_rightpoint[3], const Float:plane_point2[3], const Float:plane_point3[3], Float:line_point1[3], Float:line_point2[3]){
decl Float:plane_vec1[3];
SubtractVectors(plane_point2, plane_rightpoint, plane_vec1);
new Float:height = SquareRoot(GetVectorDotProduct(plane_vec1, plane_vec1));
ScaleVector(plane_vec1, 1/height);
decl Float:plane_vec2[3];
SubtractVectors(plane_point3, plane_rightpoint, plane_vec2);
new Float:width = SquareRoot(GetVectorDotProduct(plane_vec2, plane_vec2));
ScaleVector(plane_vec2, 1/width);
decl Float:vec[3];
decl Float:vecline[3];
SubtractVectors(line_point1, plane_rightpoint, vecline);
copyvector(plane_vec1, vec);
ScaleVector(vec, GetVectorDotProduct(vecline, plane_vec1));
decl Float:projection[3];
copyvector(vec, projection);
copyvector(plane_vec2, vec);
ScaleVector(vec, GetVectorDotProduct(vecline, plane_vec2));
AddVectors(vec, projection, projection);
decl Float:distancevector1[3];
SubtractVectors(vecline, projection, distancevector1);
SubtractVectors(line_point2, plane_rightpoint, vecline);
copyvector(plane_vec1, vec);
ScaleVector(vec, GetVectorDotProduct(vecline, plane_vec1));
decl Float:projection2[3];
copyvector(vec, projection2);
copyvector(plane_vec2, vec);
ScaleVector(vec, GetVectorDotProduct(vecline, plane_vec2));
AddVectors(vec, projection2, projection2);
decl Float:distancevector2[3];
SubtractVectors(vecline, projection2, distancevector2);
new Float:distancevector1module = SquareRoot(GetVectorDotProduct(distancevector1, distancevector1));
new Float:distancevector2module = SquareRoot(GetVectorDotProduct(distancevector2, distancevector2));
new Float:distancebetweenprojections = GetVectorDistance(projection, projection2);
if(GetVectorDotProduct(distancevector1, distancevector2) >= 0){
return false;
}else{
decl Float:vecbetweenprojections[3];
SubtractVectors(projection2, projection, vecbetweenprojections);
ScaleVector(vecbetweenprojections, 1/SquareRoot(GetVectorDotProduct(vecbetweenprojections, vecbetweenprojections)));
ScaleVector(vecbetweenprojections, distancebetweenprojections*distancevector1module/(distancevector1module+distancevector2module));
decl Float:intersectpoint[3];
AddVectors(projection, vecbetweenprojections, intersectpoint);
return intersectpointinsquare(plane_vec1, height, plane_vec2, width, intersectpoint);
}
}
bool:intersectpointinsquare(const Float:plane_vec1[3], const Float:height, const Float:plane_vec2[3], const Float:width, Float:point[3]){
new Float:productbetweenvec1andpoint = GetVectorDotProduct(plane_vec1, point);
new Float:productbetweenvec2andpoint = GetVectorDotProduct(plane_vec2, point);
if(productbetweenvec1andpoint >= 0 && productbetweenvec1andpoint <= height && productbetweenvec2andpoint >= 0 && productbetweenvec2andpoint <= width){
return true;
}else{
return false;
}
}
copyvector(const Float:vec1[3], Float:vec2[3]){
vec2[0] = vec1[0];
vec2[1] = vec1[1];
vec2[2] = vec1[2];
}
//blaacky stuff which i ruined
/*
* Generates all 8 points of a zone given just 2 of its points
*/
CreateZonePoints(Float:origin[3], const Float:min[3], const Float:max[3], Float:ang[3], Float:point[8][3])
{
decl Float:f1[3];
decl Float:f2[3];
new Float:ca = Cosine(ang[0]);
new Float:sa = Sine(ang[0]);
new Float:cb = Cosine(ang[1]);
new Float:sb = Sine(ang[1]);
new Float:cc = Cosine(ang[2]);
new Float:sc = Sine(ang[2]);
f1[0] = ca*cb;
f1[1] = ca*sb;
f1[2] = -sa;
f2[0] = cc*sa*cb+sc*sb;
f2[1] = cc*sa*sb-sc*cb;
f2[2] = cc*ca;
decl Float:f3[3];
f3[0] = f1[1]*f2[2] - f1[2]*f2[1];
f3[1] = f1[2]*f2[0] - f1[0]*f2[2];
f3[2] = f1[0]*f2[1] - f1[1]*f2[0];
decl Float:fminandmax[2][3][3];
fminandmax[0][0][0] = f1[0]*min[1];
fminandmax[0][0][1] = f1[1]*min[1];
fminandmax[0][0][2] = f1[2]*min[1];
fminandmax[0][1][0] = f2[0]*min[2];
fminandmax[0][1][1] = f2[1]*min[2];
fminandmax[0][1][2] = f2[2]*min[2];
fminandmax[0][2][0] = f3[0]*min[0];
fminandmax[0][2][1] = f3[1]*min[0];
fminandmax[0][2][2] = f3[2]*min[0];
fminandmax[1][0][0] = f1[0]*max[1];
fminandmax[1][0][1] = f1[1]*max[1];
fminandmax[1][0][2] = f1[2]*max[1];
fminandmax[1][1][0] = f2[0]*max[2];
fminandmax[1][1][1] = f2[1]*max[2];
fminandmax[1][1][2] = f2[2]*max[2];
fminandmax[1][2][0] = f3[0]*max[0];
fminandmax[1][2][1] = f3[1]*max[0];
fminandmax[1][2][2] = f3[2]*max[0];
for(new i = 0; i < 8; i++){
new Float:vec[3] = {0.0, 0.0, 0.0};
for(new j = 0; j < 3; j++){
AddVectors(vec, fminandmax[((i >> (2-j)) & 1) * 1][j], vec);
}
AddVectors(vec, origin, point[i]);
}
}
//this is the only part that stills neat, as i didn't touch it.
/*
* Graphically draws a zone
* if client == 0, it draws it for all players in the game
* if client index is between 0 and MaxClients+1, it draws for the specified client
*/
DrawZone(client, Float:array[8][3], beamsprite, halosprite, color[4], Float:life)
{
for(new i=0, i2=3; i2>=0; i+=i2--)
{
for(new j=1; j<=7; j+=(j/2)+1)
{
if(j != 7-i)
{
TE_SetupBeamPoints(array[i], array[j], beamsprite, halosprite, 0, 0, life, 5.0, 5.0, 0, 0.0, color, 0);
if(0 < client <= MaxClients)
TE_SendToClient(client, 0.0);
else
TE_SendToAll(0.0);
}
}
}
}
sorry if it's bad documented or not documented at all. it is still just drafts, it probably has a lot of bugs. but, well, here is a quick documentation about the most important functions:
setupentitysphere makes a sphere on an entity big enough to contains its mins and maxs. the value returned is the radius of the sphere. the mins and maxs can be changed with parameters.
collidespheres is used to check if two spheres are colliding or not.
setupentityzone makes a zone on an entity based on its mins and maxs, position and angles with CreateZonePoints. the mins and maxs can also be changed.
CreateZonePoints(credits to blaacky) makes a zone with the parameters origin, mins, maxs and angles.
intersectboxes is used to check whether two sets of zone points, which must be created with CreateZonePoints, setupentityzone or by something that uses a similar enough method, are colliding or not.
i know the spheres thing aren't zones(or is it?), but i find it cool to be used before zones calculations because they are much lighter than them(this sounded funny). and, i mean, if the spheres made out of two boxes aren't colliding, there is no way those two boxes would collide. that saves a lot of unnecessary calculations.
now, what really matters: blaacky, hunter x hunter is awesome! that last scene of your profile picture character in the manga was just soo, soooo... i won't say anything! it might be a spoiler for someone.
but arghhh, bro,why don't yoshihiro togashi release more hxh manga? i neeeed it! gon sz, killua sz, killua's sister sz, chimera ants blurghh, nothing personal, though. the story is getting just so interesting, but why won't yoshihiro write it!!??? he's too slow and lazy. urghjdioasjdiuosa.
i wish i could spend more time(and waste more of your time because you are reading this) saying how much i luv that anime/manga(and other animes/mangas too), but i can't, i have school and it's already too late. dang you, school!
|