Transforming transport/boat's coordinate system menu

User Tag List

Results 1 to 15 of 15
  1. #1
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Transforming transport/boat's coordinate system

    So I recall seeing a thread on how to transform the boat/transport's coordinate system to basically match all other game objects. Does anyone have any other information on this?

    i.e. where the matrix is located w/respect to object base, ad well as the math required to transform the given position?

    Thanks in advance! After searching I could only find http://www.mmowned.com/forums/world-...ect-boats.html which doesn't really speak to it in too much detail.

    And then separately, how can I understand any object's current position when standing on the boat w/relation to the world around them (i.e. not like {1,-2,-3}, but like {1000.0, 1256.0, -2123.0})
    https://tanaris4.com

    Transforming transport/boat's coordinate system
  2. #2
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You transform any relative location by the transports world matrix.
    In the Windows binary, the world matrix for gameobjects is located at +0x1D0 (not a pointer), and is a standard 4x4 matrix. Virtual function 52 in CGObject_C gets the world matrix for any object (note that transports can also be units, it's not only gameobjects!).
    Transforming can be done with:
    Code:
    public static void Transform(ref Vector3 v, ref Matrix m, out Vector3 result)
    {
        float x = v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31 + m.M41;
        float y = v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32 + m.M42;
        float z = v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33 + m.M43;
        result.X = x;
        result.Y = y;
        result.Z = z;
    }
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  3. #3
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the post, worked perfectly. One question, what is the mathematical term for that type of transformation?
    https://tanaris4.com

  4. #4
    caytchen's Avatar Contributor
    Reputation
    138
    Join Date
    Apr 2007
    Posts
    162
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you only get the final world matrix, it can be any number of transformations (and translations) combined. Also see Transformation matrix - Wikipedia, the free encyclopedia

  5. #5
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    The technical term is a matrix transformation. It comes specifically from linear algebra. It is used heavily in computer graphics.

  6. #6
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    .Net includes built in Vector3D, Point3D, and Matrix3D primitives that all support "doing the right thing" when you add, multiply, etc. them. So, if you're in C#:

    Code:
    Matrix3D transform;
    Vector3D facing;
    var newFacing = facing * transform; // et voila!
    If you want to get all fancy, there's even a built-in Quaternion class that "does the right thing" for 3D facing operations.

    I use matrix transforms extensively in my steering lib, and it has cut down significantly on errors and lines of code. It's also a great deal more performant than my old, buggy, hand-rolled version; I can only assume that the MS CLR guys tuned the code carefully since this stuff is heavily used by the managed portions of the XNA libraries.
    Don't believe everything you think.

  7. #7
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by amadmonk View Post
    .Net includes built in Vector3D, Point3D, and Matrix3D primitives that all support "doing the right thing" ... I can only assume that the MS CLR guys tuned the code carefully since this stuff is heavily used by the managed portions of the XNA libraries.
    Those classes you've linked to are actually part of WPF not XNA and are all based on doubles instead of floats (XNA uses floats, see Vector3 here). Either way, Tanaris4 is on Mac (PocketGnome).

  8. #8
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    And?

    Most of the folks on here use .Net in one form or another.
    Don't believe everything you think.

  9. #9
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by amadmonk View Post
    And?

    Most of the folks on here use .Net in one form or another.
    I'll be deep in the cold hard ground before I let you take my C++ away from me!!!

  10. #10
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    All-

    Thanks for the help here! This is my implementation for mac (yes it's not great, but I think it's the most "efficient"):

    Code:
    // assumption: arrays are of size 16!!!
    - (BOOL)invertMatrix:(float*)m withOut:(float*)mOut{
    	
    	double inv[16], det;
    	int i = 0;
    	
    	inv[0] =   m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
    	inv[4] =  -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15] - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
    	inv[8] =   m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15] + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
    	inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14] - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
    	inv[1] =  -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15] - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
    	inv[5] =   m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15] + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
    	inv[9] =  -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15] - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
    	inv[13] =  m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14] + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
    	inv[2] =   m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15] + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
    	inv[6] =  -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15] - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
    	inv[10] =  m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15] + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
    	inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14] - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
    	inv[3] =  -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11] - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
    	inv[7] =   m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11] + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
    	inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11] - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
    	inv[15] =  m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10] + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
    	
    	det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
    	if (det == 0){
    		log(LOG_ERROR, @"Unable to invert matrix! Noooo!");
            return NO;
    	}
    	
    	det = 1.0 / det;
    	
    	for (i = 0; i < 16; i++){
            mOut[i] = inv[i] * det;
    	}
    	
    	return YES;
    }
    
    // transform current position based on this transport's world matrix
    - (Position*)transformWithTransport:(WoWObject*)transport andInvert:(BOOL)invert{
    	
    	MemoryAccess *memory = [[Controller sharedInstance] wowMemoryAccess];
    	
    	// get our matrix from the transport
    	float m[16] = {0.0f};
    	if ( [memory loadDataForObject: self atAddress:[transport baseAddress] + BaseField_WorldMatrix Buffer: (Byte*)&m BufLength: sizeof(m)] ){
    		return [self transformWithMatrix:(float*)&m andInvert:invert];
    	}
    	
    	return nil;
    }
    
    // we have the world matrix already? ezmode lets just transform it!
    - (Position*)transformWithMatrix:(float*)m andInvert:(BOOL)invert{
    	
    	float matrix[16] = {0};
    	
    	// invert the matrix?
    	if ( invert ){
    		[self invertMatrix:m withOut:(float*)&matrix];
    		m = matrix;		
    	}
    	
    	// time to transform
    	float x = self.xPosition*m[0] + self.yPosition*m[4] + self.zPosition*m[8] + m[12];
    	float y = self.xPosition*m[1] + self.yPosition*m[5] + self.zPosition*m[9] + m[13];
    	float z = self.xPosition*m[2] + self.yPosition*m[6] + self.zPosition*m[10] + m[14];
    			
    	return [[[Position positionWithX:x Y:y Z:z] retain] autorelease];	
    }
    https://tanaris4.com

  11. #11
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by amadmonk View Post
    .Net includes built in Vector3D, Point3D, and Matrix3D primitives that all support "doing the right thing" when you add, multiply, etc. them. So, if you're in C#:

    Code:
    Matrix3D transform;
    Vector3D facing;
    var newFacing = facing * transform; // et voila!
    If you want to get all fancy, there's even a built-in Quaternion class that "does the right thing" for 3D facing operations.

    I use matrix transforms extensively in my steering lib, and it has cut down significantly on errors and lines of code. It's also a great deal more performant than my old, buggy, hand-rolled version; I can only assume that the MS CLR guys tuned the code carefully since this stuff is heavily used by the managed portions of the XNA libraries.
    None of those classes are used in XNA libraries.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  12. #12
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by MaiN View Post
    None of those classes are used in XNA libraries.
    Erm, yeah you're right. There ARE XNA versions, but those versions I linked to are WPF-based. But the good news is that you don't have to have a WPF app to use these primitives, and they're super useful.

    (And my point about "they must be optimized if XNA uses them" is still valid if you just substitute "WPF" for "XNA")

    Dear Microsoft: please stop introducing multiple copies of the same primitives.

    Somehow this thread turned from "hey, here's a super easy way to do matrix transforms in .Net" to "what is the flight speed of an unladen African swallow?"
    Don't believe everything you think.

  13. #13
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by amadmonk View Post
    Erm, yeah you're right. There ARE XNA versions, but those versions I linked to are WPF-based. But the good news is that you don't have to have a WPF app to use these primitives, and they're super useful.

    (And my point about "they must be optimized if XNA uses them" is still valid if you just substitute "WPF" for "XNA")

    Dear Microsoft: please stop introducing multiple copies of the same primitives.

    Somehow this thread turned from "hey, here's a super easy way to do matrix transforms in .Net" to "what is the flight speed of an unladen African swallow?"
    I don't see how these things can be optimized. They are just a bunch of floating point operations; and they also are from Microsoft's side.
    By "a great deal more performant" you would have to have coded an awful matrix class to get this phenomenon.
    What I find annoying by using classes like this is the types they use internally. Matrix3D and Vector3D use doubles - something that is rarely used in WoW. When you wish to build your matrix and transform points by your matrix, you have to go and convert from float -> double -> float.
    For this reason one could believe that using these classes in WPF is actually less performant than rolling your own; which isn't hard, because this stuff is very known and has many implementations.

    EDIT: Also, often you find that these math classes provided by .NET are missing that-one-method that you just need, and it becomes even more annoying. Notably Point and PointF in System.Graphics which miss stuff like Normalize, division-by-scalar and multiplication-by-scalar.
    Last edited by MaiN; 02-05-2011 at 11:12 AM.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  14. #14
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The hand-coded versions I wrote WERE horrible. The reason I was posting these links is not to say "hey guys, these are the fastest ones ANYWHERE" but rather to say "hey guys, you don't have to roll your own and possibly introduce a whole new set of bugs, and especially the more complicated ops like on the Quats and some of the Matrix transforms, you don't have to write and debug the code because hey, here's a pre-built, fast-enough version that for the most part 'just works'."

    I'm a HUGE fan of "don't roll your own unless you HAVE to."

    WRT to the few missing methods, since this is .Net (and .Net *usually* means C#), extension methods FTW!

    If you don't want to use them, by all means, roll your own. Tanaris is on the Mac, and lots of people don't use .Net at all. But if you DO use .Net, and you don't want to have to write your own custom code for primitives like this, and you're satisfied with primitives that are fast enough to be used by the BCL for WPF stuff... enjoy.

    And with that, I'm seriously going to stop arguing about how many angels can dance on the head of a pin -- no good deed goes unpunished, around here :P

    Edit: forgot to add; WRT to the doubles/floats -- really? One cast when you pull some data from native, and one cast when you poke it back (and otherwise leave it as doubles), and that's somehow insanely burdensome? I guess to each their own.
    Last edited by amadmonk; 02-05-2011 at 12:20 PM.
    Don't believe everything you think.

  15. #15
    XTZGZoReX's Avatar Active Member
    Reputation
    32
    Join Date
    Apr 2008
    Posts
    173
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How about, use a library that actually IS optimized (under Mono, through SIMD): https://github.com/mhutch/Mono.GameMath - my fork contains pending commits for upstream: https://github.com/XTZGZoReX/Mono.GameMath

    In addition, the core functions in the library are hand-optimized through knowledge of the memory model, inlining, etc.

    (Also, yes, it will run under MS.NET, but there you just don't get any SSE.)
    Last edited by XTZGZoReX; 02-05-2011 at 02:54 PM.

Similar Threads

  1. Replies: 3
    Last Post: 07-17-2012, 11:42 AM
  2. coordinate system
    By Sillyboy72 in forum WoW Memory Editing
    Replies: 5
    Last Post: 06-29-2012, 08:46 AM
  3. lvl 68-79 Use LFD as a transportation system.
    By imisswalljumping in forum World of Warcraft Exploits
    Replies: 14
    Last Post: 04-13-2010, 02:10 AM
  4. Boat mounting guide
    By bloodofwar in forum World of Warcraft Guides
    Replies: 5
    Last Post: 05-26-2006, 03:18 PM
  5. Replies: 0
    Last Post: 03-24-2006, 01:43 AM
All times are GMT -5. The time now is 09:00 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search