Jump to content
  • Advertisement

Finalspace

Member
  • Content count

    549
  • Joined

  • Last visited

Community Reputation

1183 Excellent

About Finalspace

  • Rank
    Advanced Member

Personal Information

Social

  • Github
    f1nalspace

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Finalspace

    Why are enums broken

    Thats it - great that somebody actually brings that up! And guess what, i am one of such a person who actually only uses the features that they want and dont accept new ones until i evaluated and weighted them by a lot of categories.
  2. In OpenGL you can have subpixel accuracy when bilinear filtering is active. So a fragment is one of that subpixels, but when nearest filter is active - a fragment equals one pixel. Also a fragment is always a filled portion of a geometric object, such as a triangle, quad, etc - A pixel is just one point on your screen - not necessarily to be filled. Oh and fragments are defined in clip-space and pixels are obviously in screen space. https://www.khronos.org/opengl/wiki/Fragment_Shader And if you are really want to know how a 3D renderer such as OpenGL works, you can check out: https://www.youtube.com/watch?v=Y_vvC2G7vRo&list=PLEETnX-uPtBUbVOok816vTl1K9vV1GgH5
  3. Finalspace

    Predict enemy position on multiple variables

    Indeed there was a bug when i computed the bullet distance (Speed was not converted to a distance), now it is: float bulletDistance = Vec2Length(distanceToEnemy) / (tower.data->bullet.speed / input.deltaTime);
  4. Finalspace

    Predict enemy position on multiple variables

    I nailed it: if(tower.hasTarget) { assert(tower.targetEnemy != nullptr); Creep *enemy = tower.targetEnemy; // First we compute how many frames we need until we can actually fire (Weapon cooldown) float framesRequiredToFire = (tower.gunTimer / input.deltaTime); float timeScale = Max(framesRequiredToFire, 1.0f); // Now we predict the enemy position based on the enemy speed and the number of frames required to fire Vec2f predictedPosition = enemy->position + enemy->facingDirection * enemy->speed * input.deltaTime * timeScale; Vec2f distanceToEnemy = predictedPosition - tower.position; // Second we compute how many frames we need the bullet to move to the predicted position assert(tower.data->bullet.speed > 0); float bulletDistance = Vec2Length(distanceToEnemy) / tower.data->bullet.speed; float framesRequiredForBullet = (bulletDistance / input.deltaTime); // Now we recompute the time scale and the predicted enemy position timeScale = Max(framesRequiredToFire + framesRequiredForBullet, 1.0f); predictedPosition = enemy->position + enemy->facingDirection * enemy->speed * input.deltaTime * timeScale; distanceToEnemy = predictedPosition - tower.position; // Smoothly rotate the gun Vec2f directionToEnemy = Vec2Normalize(distanceToEnemy); float angleToEnemy = Vec2AxisToAngle(directionToEnemy); float deltaAngle = angleToEnemy - tower.facingAngle; float anglePositiveIncrement = deltaAngle < 0 ? -1.0f : (deltaAngle > 0.0f ? 1.0f : 0.0f); if(!tower.gunIsRotating) { tower.rotationTimer[0] = 0; tower.rotationTimer[1] = 1.0f / tower.data->gunRotationSpeed; float anglePerFrame = Min(Pi32 / tower.rotationTimer[1], Abs(deltaAngle)); tower.targetAngle[0] = tower.facingAngle; tower.targetAngle[1] = tower.facingAngle + anglePerFrame * anglePositiveIncrement; tower.gunIsRotating = true; } else { assert(tower.rotationTimer[1] > 0); tower.rotationTimer[0] += input.deltaTime; if(tower.rotationTimer[0] > tower.rotationTimer[1]) { tower.rotationTimer[0] = tower.rotationTimer[1] = 0; tower.targetAngle[0] = tower.targetAngle[1] = 0; tower.gunIsRotating = false; } else { float t = tower.rotationTimer[0] / tower.rotationTimer[1]; tower.facingAngle = ScalarLerp(tower.targetAngle[0], t, tower.targetAngle[1]); } } // Fire when we have a target in sight if(tower.canFire) { Vec2f lookDirection = Vec2AngleToAxis(tower.facingAngle); float maxDistance = Vec2Length(distanceToEnemy) + enemy->data->collisionRadius; LineCastInput input = {}; input.p1 = tower.position + lookDirection * tower.data->gunTubeLength; input.p2 = input.p1 + lookDirection * maxDistance; input.maxFraction = 1.0f; LineCastOutput output = {}; bool willHit = LineCastCircle(input, predictedPosition, enemy->data->collisionRadius, output); if(willHit) { towers::ShootBullet(*state, tower); } } }
  5. How do i predict the enemy position, so the bullet will always hit it - regardless how fast the enemy moves, including other variables such as: - Enemy speed - Weapon cooldown - Bullet speed - Gun facing direction - Gun rotation speed My current approach is very simple, so does it not work always: // @TODO(final): Much better prediction scheme // Multiply delta time by some factor computed by: // - Gun cooldown // - Bullet Speed // - Gun Rotation Speed/Delta Vec2f predictedPosition = enemy->position + enemy->facingDirection * enemy->speed * input.deltaTime; Vec2f distanceToEnemy = predictedPosition - tower.position; Vec2f directionToEnemy = Vec2Normalize(distanceToEnemy); float angleToEnemy = ArcTan2(directionToEnemy.y, directionToEnemy.x); constexpr float tolerance = 0.1f; float delta = angleToEnemy - tower.facingAngle; if(Abs(delta) > tolerance) { float inc = delta < 0 ? -1.0f : 1.0f; float value = Min(input.deltaTime, Abs(delta)); tower.facingAngle += tower.data->gunRotationSpeed * value * inc; } Is there a better approach?
  6. Finalspace

    Why are enums broken

    True, but you can access each member inside it without specify the enum at all, which makes each value pretty much a constant. Example: namespace abc { enum OldCPPEnum { A, B, C }; static void OldCppEnumTest() { OldCPPEnum x = OldCPPEnum::B; OldCPPEnum y = A; } } namespace cba { static void OldCppEnumTest() { abc::OldCPPEnum x = abc::B; abc::OldCPPEnum y = abc::OldCPPEnum::A; } }
  7. Finalspace

    Why are enums broken

    No i dont want to use bitset or anything else from the STL - just to get grouped flags. I think its just stupid that its not part of the language itself. Object pascal has it since ages, set of and other useful features: http://www.delphibasics.co.uk/Article.asp?Name=Sets Enums until C++/11 are pretty much useless in my opponion. Why? All enum values are in the global namespace + Weak compile time validation.
  8. Finalspace

    Why are enums broken

    The main problem is: Enums are often misused as flags and even i use it that way, because i want my flags to be grouped. A group of flags which can be validated is much safer and easier to use than random constants with a special naming convention. Randoms constants defined in a namespace is not the same as grouped flags - you wont get compile error validation! My way of doing it is the following: #define ENUM_AS_FLAGS_OPERATORS(etype) \ inline etype operator | (etype a, etype b) { \ return static_cast<etype>(static_cast<int>(a) | static_cast<int>(b)); \ } \ inline bool operator & (etype a, etype b) { \ return (static_cast<etype>(static_cast<int>(a) & static_cast<int>(b))) == b; \ } \ inline etype& operator |= (etype &a, etype b) { \ return a = a | b; \ } enum class MyEnumAsFlags : int { None = 0, A = 1 << 0, B = 1 << 1, C = 1 << 2, }; ENUM_AS_FLAGS_OPERATORS(MyEnumAsFlags); But this is a stupid and should not be required - really there should be a something like this (without requiring any templated whatsoever, it should just be part of the language): // For flags just make it clear its a enumeration of flags (First entry is 1, second is 2, third is 4, etc.) // its so simple - dont understand why the c++ standard does not contain this enum flags MyFlags { A, // Is 1 B, // Is 2 C, // Is 4 }; enum flags MyFlags { None = 0, A = 1, B = 2 C, // C is 4 }; MyFlags w = MyFlags::A | MyFlags::B; MyFlags t = 0x3; // Compile error MyFlags f = 0x2; // Translated to MyFlags::B MyFlags d = 0; // No flags -> Totally valid to pass zero here // flags with fixed integral type enum flags MyByteFlags : int8_t { A = 0x1, B = 0x2 }; // enum class without type enum class MyChoice { None, One, Two }; MyChoice w = MyChoice::One; MyChoice t = MyChoice::One | MyChoice::Two; // Compile error MyChoice f = 1; // Compile error // enum class with fixed integral type (First entry is one always, unless its overriden) enum class MyChoice : int32_t { None = 0, One, Two }; MyChoice w = MyChoice::One; MyChoice t = MyChoice::One | MyChoice::Two; // Compile error MyChoice f = 3; // Compile error MyChoice d = 1; // Translated to MyChoice::One
  9. Finalspace

    Visual Studio 2017 usability issues

    I use visual studio 2017 too, but the community edition without any additions or plugins. And yes i have similar and other issues: - When i need auto-completion it either does not work or shows useless suggestions in C99/C++ code - Grepping (Ctrl+Semicolon) for functions or types always searches in all files, even though its set to the current file only (Bug MS will most likely never fix) -> (Using CTRL+F is not a alternative to fast jump to a function!). Also when you have multiple implementations of the same function (IFDEF) you dont know which is the declaration and which is the implementation you want to jump to - you can only guess. Also the grepping is painfully slow. - C/C++ function brief description are not showing up at all. All my declarations are commented properly but the implementations are not - so when i use a function and hover over it, it never shows me the function comment from the declararation :-( - Intellisense cannot keep up with me (Sometimes it even requires a full restart of the IDE to work properly) - C/C++ error checking seems to be much worse than in 2015, in one moment i get a range of weird errors and in the next second the errors are gone - No doxygen support at all, only the bad XML doc style bullshit and even this does not work properly But in general 2017 is a lot more stable and the load times are better, but the C/C++ parser and highlighter seems to be much slower than 2015 😞 Even though VS have all this issues, other IDE`s are much worse. For example the IDE i use on Linux CLion is much much slower than VS and it barely can handle source files with 500 KB+ and the grepping of functions is a more worse experience. And no my system is not at fault: i7 4790k (4 GHz), 16 GB low latency, NVIDIA GTX, SSD or SATA3.
  10. Okay i think converting version number part to a float was a bad idea - after looking into https://www.h-schmidt.net/FloatConverter/IEEE754.html I will go with two separate integers for each part -> Leading zero count and actual number.
  11. I have a version number as string which is exactly like this: 16.041.3.137. My goal is to parse each individual part into a floating point number, so you can use a >= as a comparison for each part. Parsing the first, third and fourth part is easy, but the second one is a little tricky. If you parse it with base 10 you get a result of 4 - which is not correct. The result of the second part "041" should be a exact floating point of 0.41. It should never round up or down. So my question is, what do i need to do to construct a floating point manually: I have the count of leading zeros and the decimal value after that. Is that possible? Thanks!
  12. Finalspace

    Box2D ignores restitution

    Solved. That must be true, otherwise you will never get a bounce: assert(state.ball->GetLinearVelocity().Length() >= b2_velocityThreshold);
  13. Hi, i am building a small game using box2D, but i am having trouble getting the bodies behave correctly. The restitution is not handled at all - it always removes the impulse along the normal when it collides :-( What i want is a ball bouncing around a fixed static area - without losing any energy when colliding. So what is wrong with my definitions? - I am using the latest Box2D from the github master branch -> Source is fully compiled in always. - My world is 20 meters in width and 11.25 in height. w = half width, h = half height. This i what i have (On initialization): b2World *world; b2Body *body; state.world = world = new b2World(b2Vec2(0, 0)); // // Field // b2BodyDef fieldDef = b2BodyDef(); fieldDef.type = b2BodyType::b2_staticBody; fieldDef.position = b2Vec2(0, 0); fieldDef.angle = 0; fieldDef.fixedRotation = true; fieldDef.linearDamping = 0; fieldDef.angularDamping = 0; state.field = body = world->CreateBody(&fieldDef); b2Vec2 fieldVertices[4] = { b2Vec2(w, h), b2Vec2(-w, h), b2Vec2(-w, -h), b2Vec2(w, -h), }; b2ChainShape fieldShape = b2ChainShape(); fieldShape.CreateLoop(fieldVertices, 4); b2FixtureDef fieldFixtureDef = b2FixtureDef(); fieldFixtureDef.shape = &fieldShape; fieldFixtureDef.restitution = 1; fieldFixtureDef.friction = 0; body->CreateFixture(&fieldFixtureDef); // // Ball // b2BodyDef ballDef = b2BodyDef(); ballDef.type = b2BodyType::b2_dynamicBody; ballDef.allowSleep = false; ballDef.bullet = true; ballDef.position = b2Vec2(0, 0); ballDef.angle = 0; ballDef.fixedRotation = true; ballDef.linearDamping = 0; ballDef.angularDamping = 0; state.ball = body = world->CreateBody(&ballDef); b2CircleShape ballShape = b2CircleShape(); ballShape.m_radius = ballRadius; ballShape.m_p = b2Vec2(0, 0); b2FixtureDef ballFixtureDef = b2FixtureDef(); ballFixtureDef.shape = &ballShape; ballFixtureDef.restitution = 1.0f; ballFixtureDef.friction = 0.0f; ballFixtureDef.density = 1.0f; body->CreateFixture(&ballFixtureDef); body->ApplyLinearImpulse(b2Vec2(0.25f, 0), state.ball->GetPosition(), true); On updating: state.world->Step(input.deltaTime, 10, 10);
  14. Finalspace

    Final Platform Layer

    About:Final Platform Layer is a Single-Header-File cross-platform C development library designed to abstract the underlying platform to a very simple and easy to use low-level api - providing low level access to (Window, Video, Audio, Keyboard, Mouse, Gamepad, Files, Threads, Memory, Hardware, etc.).The main focus is game/media/simulation development, so the default settings will create a window, setup a OpenGL rendering context and initialize audio playback on any platform.It is written in C99 for simplicity and best portability, but is C++ compatible as well.FPL supports the platforms Windows/Linux/Unix for the architectures x86/x64.It is licensed under the MIT-License. This license allows you to use FPL freely in any software.What makes it different from other platform abstraction libraries, such as SDL/SFML/etc. ?:- FPL is designed to require bare minimum linking to the OS (<i>kernel32.lib</i> / <i>libld.so</i>) only.- It does not require any dependencies or build-systems to get it running.- It has a lightweight feature set (Single window, Graphics api initialization, Raw audio samples playback, Input handling, Multithreading, Path/File IO, Atomics, OS/HW-Infos etc.)- No data hiding -> everything is accessible- It uses a fixed and small memory footprint and handles memory very gracefully.- It can be controlled by a configuration structure in very detail at startup.How do i get started?You download the latest release from the github page:https://github.com/f1nalspace/fin...lob/master/final_platform_layer.hDrop it into your C/C++ project and use it in any place you want.Define FPL_IMPLEMENTATION in at least one translation unit before including the header file.For more details you can check out the official website https://libfpl.org .Current state / Future plans:FPL is not finished yet and just supports a couple of platforms, but more platforms are already in progress or are planned. Also some features are not implemented yet or may be missing.For more details: https://libfpl.org/docs/page_todo.html
  15. Good Point! I will do that.
  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!