JM33

Members
  • Content count

    28
  • Joined

  • Last visited

Community Reputation

120 Neutral

About JM33

  • Rank
    Member
  1. Solved! Basically what I needed to do was orient the quaternion to the rocket's current orientation around the forward vector. I was only supplying the forward vector, which was not enough to know if I had any amount of "roll" around the forward vector. So I ended up making a quaternion of the current rocket rotation from the current matrix, and multiplying that by the limit_rotation quaternion from before. Then I set that back to a matrix plugged that into the rotation portion of the rockets matrix(Instead of multiplying the two matrices). [source lang="java"]Quaternion transform_rotation = Quaternion.setFromMatrix(R1Matrix).normalize(); Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize(); Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize(); Quaternion rot = head.rotBetween(newvec).normalize(); float turn_threshold = 0.999874f; // maxrot is the rockets maximum rotation angle (2) rot = Quaternion.limit_rotation(rot, turn_threshold).multQ(transform_rotation); float[] qmat = rot.toMatrix(); for (int i= 0; i< 10; i++){ R1Matrix[i] = qmat[i]; } [/source] Thank you so much Álvaro, your code worked perfectly to limit the rotation of the quaternion. [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]
  2. OK, yes I was very confused, and I never needed to solve for i,j,k in the first place. The code you gave me works as often as the original code I had with angle/axis, however with the opposite effect. Basically if my plane is upside down I hit the target, otherwise not. If I remove the lines to negate the quaternion when q.real() is less than 0, I get the original results (plane upside down = miss &amp; plane right side up = hit). If you have any suggestion or insight please let me know. I feel like this is really close to the right solution as the rotation is being correctly limited to the maximum rotation, but still needs to be inverted properly. I am wondering if there is anything that can be referenced to determine when to negate the quaternion, such as the up vectors of the rocket and target? Here is my code as-is: [source lang="java"]Vector3D targvec = new Vector3D(targetmatrix[12], targetmatrix[13], targetmatrix[14]); Vector3D R1pos = new Vector3D(R1Matrix[12], R1Matrix[13], R1Matrix[14]); Vector3D R1head = new Vector3D(R1Matrix[8], R1Matrix[9], R1Matrix[10]); Vector3D newtargvec = targvec.subtract(R1pos); newtargvec = newtargvec.normalize(); R1head = R1head.normalize(); Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize(); Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize(); Quaternion rot = head.rotBetween(newvec).normalize(); float turn_threshold = 0.9998477f; // cos(maxrot/2) = cos(1) Quaternion newq = rot.limit_rotation(rot, turn_threshold); // see Quaternion code below float[] qmat = newq.toMatrix(); Matrix.multiplyMM(R1Matrix, 0, R1Matrix, 0, qmat, 0);[/source] And my relative Quaternion functions: [source lang="java"]public Quaternion limit_rotation(Quaternion q, float min_real_part) { if (q.real() <= -min_real_part || q.real() >= min_real_part) return q; if(q.real() < 0){ q = q.multF(-1); // negate quaternion } float desired_unreal_length = FloatMath.sqrt(1 - min_real_part * min_real_part); float old_unreal_length = q.unreal().abs(); Quaternion limit = new Quaternion(min_real_part, q.x * (desired_unreal_length / old_unreal_length), q.y * (desired_unreal_length / old_unreal_length), q.z * (desired_unreal_length / old_unreal_length)); Log.i("QuatLimit", "Result = w: " + Float.toString(min_real_part) + ", x:" + Float.toString(limit.x) + ", y:" + Float.toString(limit.y) + ", z:"+ Float.toString(limit.z)); return limit; } public Quaternion(float real) { this.w = real; this.x = 0; this.y = 0; this.z = 0; } public float real() { return this.w; } public Quaternion unreal() { return new Quaternion(0, this.x, this.y, this.z); } public float abs() { return FloatMath.sqrt(x * x + y * y + z * z + w * w); } public Quaternion (float w, float x, float y, float z) { this.set(w, x, y, z); } public Quaternion multF(float scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this; } [/source]
  3. Well, I have to create my own quaternion class, and I didn't have an unreal() method so I was just trying to figure that out. I found through a search that with quaternions, i = j = k = sqrt(-1). [source lang="java"]public double unreal() { double i = FloatMath.sqrt(-1); double unreal = this.x*i + this.y*i + this.z*i; return unreal; }[/source] However, I just plugged that in and it didn't work. So I will check over some of my code.
  4. Sorry Alvaro, the documentation didn't help me as it does not show how they calculate the unreal part. If you say the unreal part is "0 + xi +yj +zk", then how do I get the value of i,j,k? In my last post I had assumed the unreal part was 0 + q.x+q.y+q.z by making i,j and k equal to 1. As I said that produced bad results. I don't think setting them to zero would work, but I also tried multiplying each by the real part "w". Again bad results. Sorry for not understanding, I think I'm struggling to understand the imaginary part of quaternions. It seems sometimes i,j,k just get dropped (meaning value of 1), and sometimes they are zero. I really appreciate your help.
  5. Yes that helps! Now the part I don't understand is the q.unreal(), what is going on there? My assumption based on q= w +xi + yj + zk is that the unreal part is x+y+z. However when I tried that I got strange results. Thank you for your help
  6. [quote name='Álvaro' timestamp='1352615473' post='4999829'] return Q(min_real_part) + q.unreal() * (desired_unreal_length / old_unreal_length); } [/quote] Sorry I only know Java, but is this returning a Quaternion that is created by a double value? I don't understand how to do that. Don't you need either "w,v" or "w,x,y,z" values?
  7. This seems to be on the right track, but I'm not sure. The part about limiting the rotation seemed to work but I am still getting inconsistent results. Same problem, when the plane turns upside down, the rocket will miss. Does it matter that I am still converting the quaternion back to a matrix (instead of converting to axis angle)? I am multiplying the converted matrix by the rockets matrix. As far as I know with quaternions, you have to convert to matrix, as I am using opengles on android. The other thing I noticed was that the limiting threshold for the quaternion worked when it shouldn't have. At first I only limited the w value to anything below the threshold. code example: [source lang="java"]Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize(); Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize(); Quaternion rot = head.rotBetween(newvec); //Get Quaternion for rotation between the two vectors float turn_threshold = FloatMath.cos(maxrot/2); // maxrot is the rockets maximum rotation angle (2) if (rot.w < turn_threshold){ rot.w = turn_threshold; } float[] qmat = rot.toMatrix(); //convert quaternion to matrix Matrix.multiplyMM(R1Matrix, 0, R1Matrix, 0, qmat, 0); [/source] This did not account for a "w" value lower than zero. However when the "w" value was near -0.9, sometimes the rocket would still hit the target. Even though this code changed the value from -0.9 to +0.99 (or cos(1)). When I tried to limit the negative W value the rocket would never hit the target.I have a much harder time visualizing quaternions so I am quite confused. Also I am not sure what you meant by scaling the other three parts after changing the W value. Do I need to just normalize it?
  8. Thanks Alvaro, I have succesfully used quaternions to achieve the full rotation to towards the target. However, I have no idea how to get a limited (x degrees) rotation from the quaternion without converting it to angle-axis. After converting and limiting the angle, I get the same results. A code example would be great, but even just an explanation of the process would help.
  9. Hi everyone, I know this is a common question but my searches are not turning up good solutions (ones that work). I have a flight simulator / jet fighter game. I have other airplanes (enemy targets) flying around in the world. I want to shoot a guided missile at the target. My original approach for this works most of the time, but sometimes fails. What I have done is found my missile's heading vector, and the vector between the missile and the target. I take the cross product of the 2 vectors to get my rotation axis vector. The angle of rotation is found by arccosine of the dot product of the cross product of my missile & target vectors. Since I do not want the missile to turn directly at the target immediately, I limit the rotation to 2 degrees. After rotating, I move the missile along its forward vector, by its speed. To explain the failure in this, let me give in an example. The game starts & out in front of my airplane is the target. For this example both objects are flying forward. If I fire the missile, it goes straight for the target and hits. However, if I roll my airplane over (upside down) the missile seems to turn the wrong direction. It will often make a big loop and eventually find the target and destroy it. It seems that the rotation angle should be negative in this case, but I don't know how to determine if I need to do so. Here is some basic code to demonstrate: [source lang="java"]Vector3D targvec = new Vector3D(targetmatrix[12], targetmatrix[13], targetmatrix[14]); Vector3D R1pos = new Vector3D(R1Matrix[12], R1Matrix[13], R1Matrix[14]); Vector3D R1head = new Vector3D(R1Matrix[8], R1Matrix[9], R1Matrix[10]); Vector3D newtargvec = targvec.subtract(R1pos); newtargvec = newtargvec.normalize(); R1head = R1head.normalize(); float angle = R1head.angleBetween(newtargvec); // acos(R1head.dotProduct(newtargvec) Vector3D rotaxis = R1head.crossProduct(newvec); rotaxis.normalize(); if (angle > 2){ angle = 2; Matrix.rotateM(R1Matrix, 0, (float) angle, rotaxis.getX(), rotaxis.getY(), rotaxis.getZ()); setMoveForwardMatrix(tempMatrix, -(movedist),R1Matrix[8], R1Matrix[9], R1Matrix[10]); Matrix.multiplyMM(R1Matrix, 0, tempMatrix, 0, R1Matrix, 0); [/source]
  10. I had an idea for a table of common video game terms and translation into common languages. I wasn't thinking of a complex glossary, maybe just 25-50 of the most common terms that would be used in almost every video game. For example, score, high score, level, settings/options, controls, play/start, quit/exit, lives (number of), back/next, forward/previous. Mostly the terms that a video game menu would include. Members here could add input as to their native languages to improve the accuracy. I've been searching the web for a while now and have not come across anything like this. Surely most of these can be easily translated with Google translate or something like it, but some words don't always translate the same in the context of a video game. I think this would be a useful tool for developers here, what do you guys think?
  11. Multiple moving objects

    Thanks Artes, but as far as I have read the only way for me to achieve this is through the use of matrices. I am trying to get six degrees of freedom, rotation on 3 axis and movement on x,y,z. The main problem with using glRotate is the gimabal lock issue, where if I rotate on one axis the next rotation is no longer on the global axis used by glRotate. (Using glGetFloatv to return the values of the MODELVIEW matrix does not work in Android). Using matrices the result of the first rotation gives a new axis for the second rotation. The only other solution I have read about uses quaternions, but those are then converted to matrices. Someone can correct me if I am wrong about this, but as far as I know one of those two methods have to be used. I would love to have a simpler way to do it. I understand matrices at a minimum level. However once I start getting two or three sets of matrices, and their inversions, I just have a hard time wrapping my head around what is actually going on.
  12. Multiple moving objects

    Thanks again haegarr. That is a lot to digest, but I think I get most of it. Implementing it will take me a while, but I am patient and dilligent. I took a look around for some matrix/vector libraries. It seems there is not a lot out there specific for android/java, that seemed too specific for 3d graphics. I did find libgdx, which is to my knowledge more of a full engine. It definitely has some good matrix, vector, and quaternion classes in it. I like that it is cross platform so I can do some testing strictly on windows. I think I'll get my feet wet with that and come back to this once I'm a bit more comfortable with it. Thank you very much again for your insight.
  13. Multiple moving objects

    I am really struggling with this still. First of all, I am not quite sure I understand the way I would make my plane fly through the scene and follow it with the camera. If the camera moves, and technically opengl has no camera, then I still have to move the world around inversely of how the plane actually moves. The way I was attempting this originally accomplishes this, though maybe not the best way. Maybe I wasn't saying it correctly, but when I stated that the world moves around the plane, I guess I meant that the world is moving (inversely) around to give the effect of the camera moving through the world. (For what its worth, I also have a third person camera setup, and my plane is not actually at 0,0,0 but at 0,-4,-40. I get the same problems if I move it to 0,0,0 though) Nevertheless I tried a couple of ways to make this work differently. One was to try to move the plane with the same transform matrix I was using to move the world. I started by adding a gluLookat call at the beginning of the code so the camera could follow the plane. The main problem I came across was that I ran into a gimbal lock issue. The plane would only rotate on the world's X and Z axis. (My controls are only setup to pitch and roll the plane). I also realized that the gluLookat call isn't really a camera, it is just a (inverted) transform matrix, so again, I was still moving the landscape around to simulate the camera. My next approach I just accepted the fact that the camera (inverse landscape movement) has to be there, or else everything would just stay still. So I made an inverse matrix for the original transform matrix that I used to move my camera. I tested the matrix under the assumption that it should perform the exact opposite transformations as my original transform matrix. Therefore it should appear that the plane flies backwards and the controls are inverted (pitch up is now pitch down etc.) The matrix worked exactly that way. Then I started my drawing with the original transformation matrix (set my camera), and draw the landscape. Then I use glMultMatrixf with the inverse matrix I created, and draw the airplane. This works at first. The plane is moving along in front of the camera, but when I roll the plane seems to roll around the world's z-axis, not the local z axis. And if I pitch up/down the plane disappears completely from the scene. Even if I make a loop it never comes back. If you are still with me here, I have two questions. First, am I on the right track with these attempts? Second, why don't the transform matrices work when applied to the object when they work fine to control the camera? My best guess is that I need to create the matrix differently for the objects than I do for the camera, but I am not sure where to begin. Any help would be greatly appreciated. If you would like me to post some code to help explain what I am doing I will gladly do so. Thanks!
  14. Multiple moving objects

    Thanks haegarr. I think that if nothing else, it is easier for me to conceptualize a world full of objects and the plane flying through it. Even though it should be possible, everything really feels backwards as I am setup now. I don't think it will be much trouble to turn things around this early in my project. Like you said, simplicity of understanding, will be the main reason for me. I really appreciate the time you took to explain the details for me. Thank you very much!
  15. Multiple moving objects

    [quote name='haegarr' timestamp='1306576648' post='4816735'] In other words, IMHO letting "the world move instead of the camera" is a disservice. [/quote] I will read over the rest more carefully, but as I understand this statement, I should probably use a different approach. Very simply, as it stands my airplane doesn't move around the world. My world is moving around the airplane. If I were to reverse this process, my world would be fixed and the airplane actually moving through it. I believe this would simplify things for me greatly. The rocket then would follow the same transforms as the airplane. At the moment of release it could just use the current forward vector of the airplane and continue on its own. Other things like collision detection and enemy/target placement would also be simplified, at least as best as I can visualize it without trying. Am I wrong, or misunderstanding again? Would you do this differently, as I described? Sorry to bother you but I would rather start over with a better approach than continue fighting this.