bullet(float xx, float yy, float zz, float x1, float y1, float z1,..) {
x=xx, y=yy, z=zz; //sets origin
t[0]=x1-xx, t[1]=y1-yy, t[2]=z1-zz; //sets vec toward target i.e. r=r1-r2?
norm(t); //normalize
//other stuff
}
Vectors and bullet aiming. [Getting inconsistent results :( ]
The bullet that I'm using has a constructor like this:
When I shoot I do:
bullet *p = new bullet(player.x,player.y,player.z,player.x-player.f.x,player.y-player.f.y,player.z-player.f.z,...);
Note that f is player's forward vector and I'm sending (player.x MINUS player.f.x) because for whatever reason my forward vector is opposite to my direction of motion. As far as the player is concerned, this works perfectly.
But I get super inconsistencies when it comes to having other object aim at player:
bullet *p = new bullet(x,y,z,player.x,player.y,player.z,...);
Shouldn't this code work? What I'm getting is the enemies hitting player only when it is in certain areas around the enemy. Otherwise it's pretty hopeless.
I tried it without normalizing the vector t and it showed a line from the enemy to the player which at least suggests that something is working right. Where am I going wrong with this? Thanks.
[Here's how I update bullet position, in case there's something wrong here:
x+=(speed*t[0]);
y+=(speed*t[1]);
z+=(speed*t[2]);
]
I think your problem is probably not in the code you have posted. Try to find a specific example where the code doesn't do the right thing, and check by hand if all the computations make sense. You can post the specific example if you need help understanding it.
Well, as I said I don't understand why the enemies are shooting at random directions for few seconds (I made it so that it shoots continuously) most of the time and at the target for the rest. I tried some alterations and it seems that it is not moving in the direction that it should with the x+=speed*t[0] etc. code. Shouldn't ray tracing just be about getting a normalized vector and multiplying a scalar with it?
you should really use a vector class, that would help you a lot and make the code more bearable to read.
here's an example
your code would look like
Otherwise, it looks like it's somewhere else in the code. maybe the normalisation is wrong?
[Edited by - oliii on June 17, 2008 8:02:52 AM]
here's an example
inline void myDebugBreak(const char* assertString, const char* file, int line){ char buff[512]; sprintf_s(buff, sizeof(buff), "file \"%s\", line(%d) : assert(%s) failed.\n", file, line, assertString); fprintf(stderr, buff); DebugBreak(); }#define myAssert(A) { if(!(A)) { myDebugBreak(#A, __FILE__, __LINE__); } };class Vector{public: union { float coord[3]; // coords as an array struct { float x, y, z; }; // coords are a triple }; Vector() {} Vector(float ix, float iy, float iz) : x(ix) , y(iy) , z(iz) {} Vector(const float* icoord) : x(icoord[0]) , y(icoord[1]) , z(icoord[2]) {} Vector(const Vector& other) : x(other.x) , y(other.y) , z(other.z) {} float operator[](int i) const { myAssert(i >= 0 && i < 3); return coord; } float& operator[](int i) { myAssert(i >= 0 && i < 3); return coord; } Vector& operator+=(const Vector& other) { x += other.x; y += other.y; z += other.z; return *this; } Vector& operator-=(const Vector& other) { x -= other.x; y -= other.y; z -= other.z; return *this; } Vector& operator*=(float k) { x *= k; y *= k; z *= k; return *this; } Vector& operator/=(float k) { myAssert(fabs(k) > 1.0E-8f); float ik = 1.0f / k; return (*this) *= ik; } Vector operator+(const Vector& other) const { Vector temp(*this); return temp += other; } Vector operator-(const Vector& other) const { Vector temp(*this); return temp -= other; } Vector operator*(float k) const { Vector temp(*this); return temp *= k; } Vector operator/(float k) const { Vector temp(*this); return temp /= k; } Vector operator-() const { return Vector(-x, -y, -z); } friend Vector operator*(float k, const Vector& v) { return v * k; } Vector scaleProduct(const Vector& other) const { return Vector((x*other.x), (y*other.y), (z*other.z)); } Vector crossProduct(const Vector& other) const { return Vector((y*other.z) - (z*other.y), (z*other.x) - (x*other.z), (x*other.y) - (y*other.x)); } float dotProduct(const Vector& other) const { return (x*other.x) + (y*other.y) + (z*other.z); } Vector operator&(const Vector& other) const { return crossProduct(other); } // cross product operator Vector operator^(const Vector& other) const { return scaleProduct(other); } // scale product operator float operator*(const Vector& other) const { return dotProduct(other); } // dot product operator float lengthSquared() const { return (x*x + y*y + z*z); } float length() const { return sqrt(lengthSquared()); } Vector normalised() const { float l = length(); if(fabs(l) < 1.0E-8f) { myAssert(!"zero-length vector cant be normalised"); return Vector(1, 0, 0); } return (*this) / l; } float normalise() { float l = length(); if(fabs(l) < 1.0E-8f) { myAssert(!"zero-length vector cant be normalised"); x = y = z = 0.0f; return 0.0f; } (*this) /= l; return l; }};
your code would look like
bullet::bullet(const Vector& origin, const Vector& target, ...) { m_position = origin; m_direction = (target - origin); m_direction.normalise();}bullet::update(){ m_position += m_direction * m_speed;}bullet *p = new bullet(player.m_position, player.m_position - player.m_forward, ...);// or...
Otherwise, it looks like it's somewhere else in the code. maybe the normalisation is wrong?
[Edited by - oliii on June 17, 2008 8:02:52 AM]
Wow! What an awesome post! Yeah I guess I'll have to switch to a vector class sometime. Not quite my question but thanks!
As I went over the normalization function I sort of found this:
v[0]=v[0]/mag(v);
v[1]=v[1]/mag(v);
...
I should really be kicking myself for being such a dolt.
Either way, however, the aiming is still off and I'm positive there's no more mistakes in the code. Only after increasing the bullet speed and some quick and dirty motion planning can I hit the target. What bothers me is that my previous efforts ditching vectors and using angles (atan2()) instead gave way better results. Anyway, thanks for info.
As I went over the normalization function I sort of found this:
v[0]=v[0]/mag(v);
v[1]=v[1]/mag(v);
...
I should really be kicking myself for being such a dolt.
Either way, however, the aiming is still off and I'm positive there's no more mistakes in the code. Only after increasing the bullet speed and some quick and dirty motion planning can I hit the target. What bothers me is that my previous efforts ditching vectors and using angles (atan2()) instead gave way better results. Anyway, thanks for info.
yep, that normalisation is wrong :)
Using a vector class is not only more efficient and easier on the eye, it makes it easier to catch bugs like these, it's easy to get a sign wrong and not notice.
One word of caution with operators, be careful of their precedence.
Using a vector class is not only more efficient and easier on the eye, it makes it easier to catch bugs like these, it's easy to get a sign wrong and not notice.
One word of caution with operators, be careful of their precedence.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement