Jump to content
  • Advertisement

Krylloan

Member
  • Content Count

    282
  • Joined

  • Last visited

Community Reputation

142 Neutral

About Krylloan

  • Rank
    Member
  1. I want to use an interface class to describe the method of accessing an object's key value, and comparing two key values. Is there any way that I can typedef the interface's key type inside the accessor class template so that I can use it within accessor class functions? template <class C, class Object> class Foo { public: typedef C::Key T; T getValue() { return m_value; } void setValue(T value) { m_value = value; } private: T m_value; }; // interface class Bar { public: typedef int Key; bool compare(Key a, Key b) { return a == b; } }; class Mub { public: int value; }; Foo<Bar, Mub> zeep; Class Foo fails to compile because of the typedef line. Is there any way that I can define T as the type Bar::Key within the Foo scope, so that I can use it in Foo member functions like those above? Thanks for all assistance. Simon Hill
  2. Algorithmically, what would really speed things up is a dynamic OcTree. (Or something similar) Basically, this would reduce the calculation time from "NumParticles * (NumParticles / 2) * Comparison Time" (Algorithmically O(N^2)) To "NumParticles * ln(NumParticles) * Constant" (Algorithmically (approx) O(N ln(N))) Basically, if you use an algorithm like this you shouldn't be surprised at improvements on the order of 100s of times faster with enough particles. ln(base 2)1024 = approximately 10. An OcTree is basically a tree of cubes, where every cube can contain up to 8 cubes , one for every combination of top/bottom, left/right and front/back. Each cube is 1/8 the size of the parent cube, hence the name OcT. One way to use OcTrees that works well in situations like yours is to specify a maximum number of points that can occupy a cube (eg 10). Once more than 10 objects are placed into a cube, it is split into it's 8 constituent sub-cubes, and the points sorted into the correct sub-cube. When you want to check any point you just consider the cube it resides in and the neighbouring cubes that are near enough to have points that may effect the point you are currently checking. An OcTree will require quite a bit of high-quality techical code. There are probably OcTree implementations you can download, and there'll be good tutorials somewhere on the world-wide google. A Dynamic OcTree (One which doesn't have to be rebuilt every frame) is even trickier, but yet faster still. ------------------------------------------------------------------------ If an OcTree is too bulky, you might consider a simple 3-dimensional array of cubes. Then when checking a point you only have to consider the cube it occupies and, at most, all the neighbouring cubes (3x3x3 = 27 cubes). Each cube will require something like a linked-list to store all the points that it holds. A linked-list is probably the best method. Hope it helps
  3. Er (10 ^ -11) means: XOR the bits of 10 with the bits of -11. 10 = 1010b -11 = 1s11....0101b Answer = 1s11...1111b = -1. Note: Nb means N is in binary. Note: 1s = sign-bit is 1, meaning number is negative. So overall, you had 6.67 * -1 = -6.67.
  4. Krylloan

    new[]. delete[]. resize[]?

    Awesome, very useful both of you. Solved my problem perfectly. I promise to look at the standard allocator class implementation.
  5. Krylloan

    new[]. delete[]. resize[]?

    Thanks. Almost works. I'm having trouble getting the placement new to compile tho. class obj { public: obj() : x(0) {} ~obj() {} int x; }; int main() { obj *x = (obj *) ::operator new(sizeof(obj)); // Allocate memory new (x) obj; // placement new /* Other tries: new (x) obj; new (*x) obj; new (x) obj(); new (*x) obj(); obj *y = new (x) obj; */ x->~obj(); // Destructor call. ::operator delete(x); // Deallocate memory return 0; } I also tried: class obj { public: // obj() : x(0) {} obj(int y) : x(y) {} ~obj() {} int x; }; int main() { void* buf = ::operator new(sizeof(obj)); // allocate only obj* f = new(buf) obj(5); // construct only, placement new f->~obj(); // destruct only, must be done for user-defined types ::operator delete(buf); // de-allocate only return 0; } Both fail to compile on the placement new. Compiler Error: 37 ...\Main.cpp no matching function for call to `operator new(unsigned int, void*&)' note ...\<internal>:0 candidates are: void* operator new(unsigned int) As for vectors, I've looked at them a bit, but I'm using custom allocators and things get a little tricky there. If it matters, I'm using DevC++ 4.9.9.2 in Windows/x86, which uses GCC.
  6. Does anyone know how to resize an array constructed using new[], or get the current array size? eg obj *x = new obj[5]; // x = renew obj[x,7]; // Construct two new objs. printf("x has %d objs", x.size()); // Print the size of the array. x = renew obj[x,3]; // Destruct four objs. delete [] x; // Destruct the remaining three objs. Secondly, does anyone know how to force-call a constructor or destructor on any object without calling the allocation functions or modifying the object's internal functions/data. eg obj *x = (obj *)malloc(sizeof(obj)); // Manually allocate object. x->obj(); // Manually call constructor. x->~obj(); // Manually call destructor. free(x); // Manually free object. I'd prefer to use the force-call method, as it allows me to manage my allocation easier. Thanks for all assistance. Simon.
  7. What you really need to get your head around is how the space is partitioned. Lets say you have a cube of space that you want to use an octree for, and that it is 32 metres long in all directions. The root node will represent this entire 32-metres-cubed cube. But each of it's children will only represent a cube which is 1/2 the size in all directions (or 1/8 the volume). You need to have some way to figure out which cube goes where inside the parent cube. You could think of the position as (Top or Bottom, Left or Right, Front or Back). Call the front-to-back axis Z, the top-to-bottom axis Y, and the left-to-right axis X. So the top-left-front cube will have the co-ordinates X = 0 to 16, Y = 0 to 16, Z = 0 to 16, and the bottom-right-back cube will have the coordinates X = 16 to 32, Y = 16 to 32, and Z = 16 to 32. Each will have a width half that of their parent node, (1/2 * 32 = 16). A decent algorithm to chose which node goes where is: X = ParentNode.X + (nodeNumber / 4) * nodeWidth Y = ParentNode.Y + ((nodeNumber / 2) % 2) * nodeWidth Z = ParentNode.Z + ((nodeNumber % 2)) * nodeWidth Your root node will have nodeWidth = 32, and X = Y = Z = 0. Root.Node[5] will have nodeWidth = 16, and X = 16, Y = 0, Z = 16. Root.Node[5].Node[3] will have nodeWidth = 8, and X = 24, Y = 8, Z = 16. Of course, these co-ordinates are only the top-left-front of the node. When you want to add an item at a certain point, you want to traverse the octree down by checking which node contains that point, and only choosing that node to traverse. This way, if your octree is 5 nodes deep, you will only need to descend 5 nodes to find where to put the item. I'm sure there are much better explanations than mine, though (my excuse is I still haven't had breakfast yet). Just look up a decent tutorial on the web.
  8. A few notes. Firstly, when you want to post code to GameDev, use [sourse] and [/sourse] tags. (replace sourse with source). This looks like: int x() { indentedCode(); } Next, an octree node should contain up to 8 child nodes. You have used 7 for some odd reason. Using 8 will give you an array from 0 to 7 INCLUSIVE, which is 8 elements. You're also missing quite a bit of functionality there. I assume you want a "static" octree, which isn't continuously changing. But you need things like a node destructor, data adder etc. I assume you are going to put these in, though. Typically an octree is traversed using rules to speed things up, like only traverse nodes which might have an object that is within 100 units of the player. So instead of traversing every node you firstly work out where it is, physically, then you decide whether it fits the current rules. You're also mixing up your languages a bit. do() isn't a C++ keyword, unless, possibly, you were using this to perform some operation on your node.
  9. Unashamed BUMP :) (Post was re-worded and source was provided, but editing doesn't bump the post).
  10. EDIT: Sources pasted, and re-worded. I am trying to place WinMain() in a library, which will call a generic entrypoint function (here it is called "myMain"). WinMain.cpp #include <windows.h> int myMain(); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { return myMain(); } int returnSix() { return 6; } - Creates "WinMain.a" LocalMain.cpp int returnSix(); int myMain() { returnSix(); // *** THE PROBLEM LINE *** return 0; } - Linked with "WinMain.a" to create "LocalMain.exe" The above all compiles, links and executes fine when "THE PROBLEM LINE" is included. However, as soon as it is removed or commented, the linker is unable to find WinMain@16. The error message is: [Linker error] undefined reference to "WinMain@16" Any idea what is going on here? Are you required to access one function in a library from outside the library (manually) to get it to link? Environment: WinXP. Dev-C++ 5. x86. Thanks for all assistance. [Edited by - Krylloan on April 9, 2005 7:25:31 PM]
  11. Firstly, I think you're meaning you want to: 1) first pick a point in 3d space. 2) find the projection of that point onto the current camera matrix. (This is the nearest point on the camera plane to the picked point). 3) move the camera there. If that's correct, then. What you have to do is project the picked point onto your camera plane. Multiply by the inverse camera matrix, then set the Z to the current Z value, then multiply by the camera matrix. Not sure if this is the most efficient way to do it, but it's clean and it works. a) Obtain the camera matrix. I'm gonna call it C. (This is a 3x3 matrix, not the full 4x4 matrix). b) Obtain the inverse of the camera matrix. I = C ^ -1. c) Multiply the picked point (P) by the inverse camera matrix. A = P * I. d) Multiply your current location (M) by the inverse camera matrix. B = M * I. e) Set the Z (forward distance co-ordinate) to the current Z. A.z = B.z. f) Multiply the new point by the original camera matrix. N = J * C. N is now your new camera position. C is still your camera matrix. Tip: If you are doing lots of translation without changing the camera matrix, it might be a good idea to keep the initial B.z in memory until the camera matrix changes. That way your camera plane stays constant and does not suffer from rounding errors. Hope that helps. If you want clarification on anything I'll look back later.
  12. Krylloan

    Unusual compiler behaviour.

    To TheBluMage: It's compiled under standard Win32 App, not console. I get the typical windows error: "TypesTest has encountered a serious error and needs to close, blah blah etc". When I run the generated executable. If I remove the offending "b = a;" then then program completes without error.
  13. Krylloan

    Unusual compiler behaviour.

    To chollida1 / Anon Mike: Yep, running it under the debugger makes it proceed without a crash. To ZedFx: It compiles fine for me also, with the warning. It's when I run it that I get the crash. I actually found this when I was running a simple test program on data types, where some of the types didn't exist so my switch/case did not do the test for them and therefore didn't write the data to the variables that were printed afterwards. I simplified the program right down to the code I posted and got the same problem. Odd.
  14. Krylloan

    Quadtree node finding question

    Assuming your nodes are layed out like 1 2 3 4 Subtract 1 from the node value and you get 0 1 2 3 Which is a 2-bit number where the lower bit refers to the X coordinate and the higher bit refers to the Y coordinate. EXAMPLE Original: 1-4-3-2-3-1 Original Minus One: 0-3-2-1-2-0 X Coordinate: 0-1-0-1-0-0 Y Coordinate: 0-1-1-0-1-0 The X and Y coordinates can be simply thought of as binary numbers now. Subtracting 1 moves one square left (or up). Adding one moves one square down (or right). Your 8 surrounding squares are: (X-1, Y-1), (X, Y-1), (X+1, Y-1) (X-1, Y ), CENTER , (X+1, Y ) (X-1, Y+1), (X, Y+1), (X+1, Y+1) Then, after you have added or subtracted 1 from X and/or Y, simply reverse the process and you have your new node. CONTINUE EXAMPLE: (lower left) X Coordinate: 0-1-0-1-0-0 Y Coordinate: 0-1-1-0-1-0 X Coordinate - 1: 0-1-0-0-1-1 (Going left means subtract 1 from X) Y Coordinate + 1: 0-1-1-0-1-1 (Going down means add 1 to Y). Recombination: 0-3-2-0-3-3. (This is simply using the corresponding X value as the lower bit of each bit-pair and the Y value as the upper bit) Add 1 to Recombinaton: 1-4-3-1-4-4 So 1-4-3-1-4-4 is lower-left of 1-4-3-2-3-1 If you need to do this very often, and real fast, you may want to try this method when you are up to the optimising stage: 1) Pack multiple node-directions together in single words so that each direction takes up only 2 bits. (Use directions 0 to 3). 2) Shuffle (I can give you an algorithm if you are interested, but I'll have to find my one 1st) the bits so that the X coordinates are on the low bits of the word and the Y coordinates are on the high bits. 3) Separate the X and Y coordinates into two separate ints. 4) Calculate X-1, X+1, Y-1 and Y+1. 5) Unshuffle these values (I can give you another algorithm here). 6) To get the directions to a square bitwise-OR the unshuffled X value and the unshuffled Y value, then unpack the direction. NOTE: If your coordinate system looks like 1 2 4 3 (Increasing or decreasing clockwise) than you can use this formula, or something similar, to get the X value on the lower bit and the Y value on the higher bit: Hope this helps. minusOne = (value - 1) ^ ((value - 1) >> 1).
  15. Whatever way you look at it, using 16-bit color means the raster(image) takes up less memory, (or the transfer of color info to the graphics card requires less I/O bandwidth). Since reading from memory is extremely expensive (hundreds of cycles), the time it takes to extract 16-bit color info from a 32-bit (or do any 16-bit operations) word pales into insignificance. Simply put: The advantage of using lower-precision color values is data size, which often directly translates into speed. The only significant advantage of using higher-precision color values is higher quality.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!