by ZoDX32 » Thu Nov 14, 2019 10:41 am
So i wanted actor have some classes for being like variables storage, and
this is what i get:
What am i doing wrong here? (This is only main part of script)
Code: Select all
version "4.2"
const box_triangles = 12; //if no MD3 has been found, make standard box shape.
struct vector3d {
vector3 p1;
vector3 p2;
}
class Tris {
vector3 normal;
float rad; //Radius, for check
vector3 p1;
vector3 p2;
vector3 p3;
}
class PhysModel {
Array<class<Tris> > tri;
float friction;
int Type;
}
class PhysActor : Actor { //Kinda :P
class<PhysModel> Body; //This is gonna be the actor's NEW BODY! (Instead of his box shaped body)
override void PostBeginPlay() {
Actor mo, mo2; //temp actors
if(Body == null) {
//Body = new('PhysModel');
Tris tri_temp = new('Tris');
vector3 p_temp[box_triangles * 3] = {
(radius, radius/2, -height/2),
(radius, -radius/2, -height/2),
(radius, radius/2, height/2)
};
for(int i = 0; i < 1; i++) { //1 for testing, set it to "box_triangles" maybe..
tri_temp.p1 = p_temp[3 * i + 0];
tri_temp.p2 = p_temp[3 * i + 1];
tri_temp.p3 = p_temp[3 * i + 2];
Body.Tri.Push(tri_temp);
}
Body.type = 0;
}
for(int i2 = 0; i2 < Body.Tri.Size(); i2++) {
Body.Tri[i2].normal = CalculateNormal(Body.Tri[i2].p1, Body.Tri[i2].p2, Body.Tri[i2].p3);
for(int i3 = 0; i3 < 3; i3++) { //Find farthest point in triangle
vector3 temp_point;
switch(i3) {
case 0:
temp_point = Body.Tri[i2].p1;
case 1:
temp_point = Body.Tri[i2].p2;
case 2:
temp_point = Body.Tri[i2].p3;
}
mo = Spawn("MapSpot", pos + temp_point);
mo2 = Spawn("MapSpot", pos + Body.Tri[i2].normal);
Body.Tri[i2].rad = mo.Distance3D(mo2);
mo.Destroy();
mo2.Destroy();
}
}
Super.PostBeginPlay();
}
Array<class<Actor> > CheckActor; //clear after each implements, cuz this is a variable, not actor. This is CheckActor, they've been checked while nearby triangle.
override void Tick() {
for(int i = 0; i < Body.Tri.Size(); i++) {
Actor mo, mo2; //temp actors
float check_dist; //Tri's check size (or just distance from normal to points)
//Distance from tri's normal to actor
mo = Spawn("MapSpot", pos + vel); //velocity of actor
mo2 = Spawn("MapSpot", pos + Body.Tri[i].normal); //normal's position
check_dist = Body.Tri[i].rad + Distance3D(mo) + 8;
mo.Destroy();
//Find nearest actors to check
ThinkerIterator AF = ThinkerIterator.Create("Actor");
while(mo = Actor(AF.Next())) if(mo2.Distance3D(mo) <= check_dist && mo is "PhysActor" && mo != self) {
CheckActor.Push(mo);
}
mo2.Destroy();
//Finally we are done with implementing CheckActor!
//Now let's move our PhysActor!
if(CheckActor[0] != null) {
for(int i2 = 0; i2 < CheckActor.Size(); i2++) {
let pmo = PhysActor(CheckActor[i2]); //PMO - Physical Main Object :P
console.printf("checking actor %s", pmo.GetClassName());
}
}
//Clear checkactors
CheckActor.Clear();
mo.Destroy();
mo2.Destroy();
}
Super.Tick();
}
}
Script error lines:
Code: Select all
126: Body.Tri.Push(tri_temp);
128: Body.type = 0;
131: for(int i2 = 0; i2 < Body.Tri.Size(); i2++) {
163: for(int i = 0; i < Body.Tri.Size(); i++) {
Also,
Push () doesn't even work, not putting item to array index, and the array maximum index stays 0, which cause "read from address zero, write to address zero". (But
Push () does work with integers...)
Only because of arrays and classes i stuck with getting that error...
Spoiler:Full script:
Code: Select all
const box_triangles = 12; //if no MD3 has been found, make standard box shape.
struct vector3d {
vector3 p1;
vector3 p2;
}
class Tris {
vector3 normal;
float rad; //Radius, for check
vector3 p1;
vector3 p2;
vector3 p3;
}
class PhysModel {
Array<class<Tris> > tri;
float friction;
int Type;
/*
Types:
0 - Softbody, solid, simple for gaming. (Absolutely minimal CPU consumption)
= 1 - Material: Wood, Metal, Plastic, Elastic etc.
2 - Dirt, Sand, Mud.
3 - Liquid, Lava.
*/
}
class PhysActor : Actor {
vector3 CalculateNormal(vector3 v1, vector3 v2, vector3 v3) {
vector3 norm;
vector3 norm_U = v2 - v1;
vector3 norm_V = v3 - v1;
norm.x = norm_U.y * norm_V.z - norm_U.z * norm_V.y;
norm.y = norm_U.z * norm_V.x - norm_U.x * norm_V.z;
norm.z = norm_U.x * norm_V.y - norm_U.y * norm_V.x;
return norm;
}
float dott(vector3 u, vector3 v) {
return (u.x * v.x + u.y * v.y + u.z * v.z);
}
bool inside(vector3 p, vector3 p1, vector3 p2, vector3 p3) {
vector3 u = (0,0,0), v = (0,0,0), w = (0,0,0);
float uu = 0, uv = 0, vv = 0, wu = 0, wv = 0, D = 0;
u = p2 - p1;
v = p3 - p1;
uu = dott(u, u);
uv = dott(u, v);
vv = dott(v, v);
w = p - p1;
wu = dott(w, u);
wv = dott(w, v);
D = uv * uv - uu * vv;
float s = 0, t = 0;
s = (uv * wv - vv * wu) / D;
if (s < 0.0 || s > 1.0) return 0;
t = (uv * wu - uu * wv) / D;
if (t < 0.0 || (s + t) > 1.0) return 0;
return 1;
}
bool inside2(Vector3 p, float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) {
if (p.x >= xmin && p.x <= xmax && p.y >= ymin && p.y <= ymax && p.z >= zmin && p.z <= zmax) return 1;
return 0;
}
vector3 RayTris_main(vector3 RP1, vector3 RP2, vector3 p1, vector3 p2, vector3 p3) { //strictly points
vector3 v1 = p1 - p2;
vector3 v2 = p3 - p2;
float a, b, c, d;
a = v1.y * v2.z - v1.z * v2.y;
b = -(v1.x * v2.z - v1.z * v2.x);
c = v1.x * v2.y - v1.y * v2.x;
d = -(a * p1.x + b * p1.y + c * p1.z);
vector3 O = RP1;
vector3 V = RP2 - RP1;
float t;
t = -(a * O.x + b * O.y + c * O.z + d) / (a * V.x + b * V.y + c * V.z);
vector3 p = O + V * t;
float xmin = min(RP1.x, RP2.x);
float ymin = min(RP1.y, RP2.y);
float zmin = min(RP1.z, RP2.z);
float xmax = max(RP1.x, RP2.x);
float ymax = max(RP1.y, RP2.y);
float zmax = max(RP1.z, RP2.z);
if(inside(p, p1, p2, p3) && inside2(p, xmin, xmax, ymin, ymax, zmin, zmax)) return p;
return (0,0,0);
}
vector3 RayTris(vector3d vec, tris tri) { // Complete working and simplified check only by vector3d and tris (Ray and Triangle)
return RayTris_main(vec.p1, vec.p2, tri.p1, tri.p2, tri.p3);
}
class<PhysModel> Body; //This is gonna be the actor's NEW BODY.
override void PostBeginPlay() {
Actor mo, mo2; //temp actors
if(Body == null) {
//Body = new('PhysModel');
Tris tri_temp = new('Tris');
vector3 p_temp[box_triangles * 3] = {
(radius, radius/2, -height/2),
(radius, -radius/2, -height/2),
(radius, radius/2, height/2)
};
for(int i = 0; i < 1; i++) { //1 for testing, set it to "box_triangles" maybe..
tri_temp.p1 = p_temp[3 * i + 0];
tri_temp.p2 = p_temp[3 * i + 1];
tri_temp.p3 = p_temp[3 * i + 2];
Body.Tri.Push(tri_temp);
}
Body.type = 0;
}
for(int i2 = 0; i2 < Body.Tri.Size(); i2++) {
Body.Tri[i2].normal = CalculateNormal(Body.Tri[i2].p1, Body.Tri[i2].p2, Body.Tri[i2].p3);
for(int i3 = 0; i3 < 3; i3++) { //Find farthest point in triangle
vector3 temp_point;
switch(i3) {
case 0:
temp_point = Body.Tri[i2].p1;
case 1:
temp_point = Body.Tri[i2].p2;
case 2:
temp_point = Body.Tri[i2].p3;
}
mo = Spawn("MapSpot", pos + temp_point);
mo2 = Spawn("MapSpot", pos + Body.Tri[i2].normal);
Body.Tri[i2].rad = mo.Distance3D(mo2);
mo.Destroy();
mo2.Destroy();
}
}
Super.PostBeginPlay();
}
//We are done with functions and init, now finally real-time physics!
Array<class<Actor> > CheckActor; //clear after each implements, cuz this is variable but not actor. This is CheckActor, they checks while nearby triangle
override void Tick() {
for(int i = 0; i < Body.Tri.Size(); i++) {
Actor mo, mo2; //temp actors
float check_dist; //Tri's check size (or just distance from normal to points)
//Distance from tri's normal to actor
mo = Spawn("MapSpot", pos + vel); //velocity of actor
mo2 = Spawn("MapSpot", pos + Body.Tri[i].normal); //normal's position
check_dist = Body.Tri[i].rad + Distance3D(mo) + 8;
mo.Destroy();
//Find nearest actors to check
ThinkerIterator AF = ThinkerIterator.Create("Actor");
while(mo = Actor(AF.Next())) if(mo2.Distance3D(mo) <= check_dist && mo is "PhysActor" && mo != self) {
CheckActor.Push(mo);
}
mo2.Destroy();
//Finally we are done with implementing CheckActor!
//Now let's move our PhysActor!
if(CheckActor[0] != null) {
for(int i2 = 0; i2 < CheckActor.Size(); i2++) {
let pmo = CheckActor[i2]; //PMO - Physical Main Object
console.printf("checking actor %s", pmo.GetClassName());
}
}
//Clear checkactors
CheckActor.Clear();
mo.Destroy();
mo2.Destroy();
}
Super.Tick();
}
Default {
//
}
}
P.S.: About geometric functions, it's just a simple Ray Triangle intersection algorythm i found on internet, and "converted" it into zscript, which kinda works..
So i wanted actor have some classes for being like variables storage, and [url=https://puu.sh/EEuPU/d057cdd0a6.png]this[/url] is what i get: What am i doing wrong here? (This is only main part of script) [code]version "4.2" const box_triangles = 12; //if no MD3 has been found, make standard box shape. struct vector3d { vector3 p1; vector3 p2; } class Tris { vector3 normal; float rad; //Radius, for check vector3 p1; vector3 p2; vector3 p3; } class PhysModel { Array<class<Tris> > tri; float friction; int Type; } class PhysActor : Actor { //Kinda :P class<PhysModel> Body; //This is gonna be the actor's NEW BODY! (Instead of his box shaped body) override void PostBeginPlay() { Actor mo, mo2; //temp actors if(Body == null) { //Body = new('PhysModel'); Tris tri_temp = new('Tris'); vector3 p_temp[box_triangles * 3] = { (radius, radius/2, -height/2), (radius, -radius/2, -height/2), (radius, radius/2, height/2) }; for(int i = 0; i < 1; i++) { //1 for testing, set it to "box_triangles" maybe.. tri_temp.p1 = p_temp[3 * i + 0]; tri_temp.p2 = p_temp[3 * i + 1]; tri_temp.p3 = p_temp[3 * i + 2]; Body.Tri.Push(tri_temp); } Body.type = 0; } for(int i2 = 0; i2 < Body.Tri.Size(); i2++) { Body.Tri[i2].normal = CalculateNormal(Body.Tri[i2].p1, Body.Tri[i2].p2, Body.Tri[i2].p3); for(int i3 = 0; i3 < 3; i3++) { //Find farthest point in triangle vector3 temp_point; switch(i3) { case 0: temp_point = Body.Tri[i2].p1; case 1: temp_point = Body.Tri[i2].p2; case 2: temp_point = Body.Tri[i2].p3; } mo = Spawn("MapSpot", pos + temp_point); mo2 = Spawn("MapSpot", pos + Body.Tri[i2].normal); Body.Tri[i2].rad = mo.Distance3D(mo2); mo.Destroy(); mo2.Destroy(); } } Super.PostBeginPlay(); } Array<class<Actor> > CheckActor; //clear after each implements, cuz this is a variable, not actor. This is CheckActor, they've been checked while nearby triangle. override void Tick() { for(int i = 0; i < Body.Tri.Size(); i++) { Actor mo, mo2; //temp actors float check_dist; //Tri's check size (or just distance from normal to points) //Distance from tri's normal to actor mo = Spawn("MapSpot", pos + vel); //velocity of actor mo2 = Spawn("MapSpot", pos + Body.Tri[i].normal); //normal's position check_dist = Body.Tri[i].rad + Distance3D(mo) + 8; mo.Destroy(); //Find nearest actors to check ThinkerIterator AF = ThinkerIterator.Create("Actor"); while(mo = Actor(AF.Next())) if(mo2.Distance3D(mo) <= check_dist && mo is "PhysActor" && mo != self) { CheckActor.Push(mo); } mo2.Destroy(); //Finally we are done with implementing CheckActor! //Now let's move our PhysActor! if(CheckActor[0] != null) { for(int i2 = 0; i2 < CheckActor.Size(); i2++) { let pmo = PhysActor(CheckActor[i2]); //PMO - Physical Main Object :P console.printf("checking actor %s", pmo.GetClassName()); } } //Clear checkactors CheckActor.Clear(); mo.Destroy(); mo2.Destroy(); } Super.Tick(); } }[/code] Script error lines: [code] 126: Body.Tri.Push(tri_temp); 128: Body.type = 0; 131: for(int i2 = 0; i2 < Body.Tri.Size(); i2++) { 163: for(int i = 0; i < Body.Tri.Size(); i++) { [/code] Also, [color=#FFBF80]Push[/color]() doesn't even work, not putting item to array index, and the array maximum index stays 0, which cause "read from address zero, write to address zero". (But [color=#FFBF80]Push[/color]() does work with integers...) Only because of arrays and classes i stuck with getting that error... [spoiler]Full script: [code]const box_triangles = 12; //if no MD3 has been found, make standard box shape. struct vector3d { vector3 p1; vector3 p2; } class Tris { vector3 normal; float rad; //Radius, for check vector3 p1; vector3 p2; vector3 p3; } class PhysModel { Array<class<Tris> > tri; float friction; int Type; /* Types: 0 - Softbody, solid, simple for gaming. (Absolutely minimal CPU consumption) = 1 - Material: Wood, Metal, Plastic, Elastic etc. 2 - Dirt, Sand, Mud. 3 - Liquid, Lava. */ } class PhysActor : Actor { vector3 CalculateNormal(vector3 v1, vector3 v2, vector3 v3) { vector3 norm; vector3 norm_U = v2 - v1; vector3 norm_V = v3 - v1; norm.x = norm_U.y * norm_V.z - norm_U.z * norm_V.y; norm.y = norm_U.z * norm_V.x - norm_U.x * norm_V.z; norm.z = norm_U.x * norm_V.y - norm_U.y * norm_V.x; return norm; } float dott(vector3 u, vector3 v) { return (u.x * v.x + u.y * v.y + u.z * v.z); } bool inside(vector3 p, vector3 p1, vector3 p2, vector3 p3) { vector3 u = (0,0,0), v = (0,0,0), w = (0,0,0); float uu = 0, uv = 0, vv = 0, wu = 0, wv = 0, D = 0; u = p2 - p1; v = p3 - p1; uu = dott(u, u); uv = dott(u, v); vv = dott(v, v); w = p - p1; wu = dott(w, u); wv = dott(w, v); D = uv * uv - uu * vv; float s = 0, t = 0; s = (uv * wv - vv * wu) / D; if (s < 0.0 || s > 1.0) return 0; t = (uv * wu - uu * wv) / D; if (t < 0.0 || (s + t) > 1.0) return 0; return 1; } bool inside2(Vector3 p, float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) { if (p.x >= xmin && p.x <= xmax && p.y >= ymin && p.y <= ymax && p.z >= zmin && p.z <= zmax) return 1; return 0; } vector3 RayTris_main(vector3 RP1, vector3 RP2, vector3 p1, vector3 p2, vector3 p3) { //strictly points vector3 v1 = p1 - p2; vector3 v2 = p3 - p2; float a, b, c, d; a = v1.y * v2.z - v1.z * v2.y; b = -(v1.x * v2.z - v1.z * v2.x); c = v1.x * v2.y - v1.y * v2.x; d = -(a * p1.x + b * p1.y + c * p1.z); vector3 O = RP1; vector3 V = RP2 - RP1; float t; t = -(a * O.x + b * O.y + c * O.z + d) / (a * V.x + b * V.y + c * V.z); vector3 p = O + V * t; float xmin = min(RP1.x, RP2.x); float ymin = min(RP1.y, RP2.y); float zmin = min(RP1.z, RP2.z); float xmax = max(RP1.x, RP2.x); float ymax = max(RP1.y, RP2.y); float zmax = max(RP1.z, RP2.z); if(inside(p, p1, p2, p3) && inside2(p, xmin, xmax, ymin, ymax, zmin, zmax)) return p; return (0,0,0); } vector3 RayTris(vector3d vec, tris tri) { // Complete working and simplified check only by vector3d and tris (Ray and Triangle) return RayTris_main(vec.p1, vec.p2, tri.p1, tri.p2, tri.p3); } class<PhysModel> Body; //This is gonna be the actor's NEW BODY. override void PostBeginPlay() { Actor mo, mo2; //temp actors if(Body == null) { //Body = new('PhysModel'); Tris tri_temp = new('Tris'); vector3 p_temp[box_triangles * 3] = { (radius, radius/2, -height/2), (radius, -radius/2, -height/2), (radius, radius/2, height/2) }; for(int i = 0; i < 1; i++) { //1 for testing, set it to "box_triangles" maybe.. tri_temp.p1 = p_temp[3 * i + 0]; tri_temp.p2 = p_temp[3 * i + 1]; tri_temp.p3 = p_temp[3 * i + 2]; Body.Tri.Push(tri_temp); } Body.type = 0; } for(int i2 = 0; i2 < Body.Tri.Size(); i2++) { Body.Tri[i2].normal = CalculateNormal(Body.Tri[i2].p1, Body.Tri[i2].p2, Body.Tri[i2].p3); for(int i3 = 0; i3 < 3; i3++) { //Find farthest point in triangle vector3 temp_point; switch(i3) { case 0: temp_point = Body.Tri[i2].p1; case 1: temp_point = Body.Tri[i2].p2; case 2: temp_point = Body.Tri[i2].p3; } mo = Spawn("MapSpot", pos + temp_point); mo2 = Spawn("MapSpot", pos + Body.Tri[i2].normal); Body.Tri[i2].rad = mo.Distance3D(mo2); mo.Destroy(); mo2.Destroy(); } } Super.PostBeginPlay(); } //We are done with functions and init, now finally real-time physics! Array<class<Actor> > CheckActor; //clear after each implements, cuz this is variable but not actor. This is CheckActor, they checks while nearby triangle override void Tick() { for(int i = 0; i < Body.Tri.Size(); i++) { Actor mo, mo2; //temp actors float check_dist; //Tri's check size (or just distance from normal to points) //Distance from tri's normal to actor mo = Spawn("MapSpot", pos + vel); //velocity of actor mo2 = Spawn("MapSpot", pos + Body.Tri[i].normal); //normal's position check_dist = Body.Tri[i].rad + Distance3D(mo) + 8; mo.Destroy(); //Find nearest actors to check ThinkerIterator AF = ThinkerIterator.Create("Actor"); while(mo = Actor(AF.Next())) if(mo2.Distance3D(mo) <= check_dist && mo is "PhysActor" && mo != self) { CheckActor.Push(mo); } mo2.Destroy(); //Finally we are done with implementing CheckActor! //Now let's move our PhysActor! if(CheckActor[0] != null) { for(int i2 = 0; i2 < CheckActor.Size(); i2++) { let pmo = CheckActor[i2]; //PMO - Physical Main Object console.printf("checking actor %s", pmo.GetClassName()); } } //Clear checkactors CheckActor.Clear(); mo.Destroy(); mo2.Destroy(); } Super.Tick(); } Default { // } }[/code] [i]P.S.: About geometric functions, it's just a simple [b]Ray Triangle[/b] intersection algorythm i found on internet, and "converted" it into zscript, which kinda works..[/i][/spoiler]