Jump to content

reepblue

Developers
  • Posts

    2,600
  • Joined

  • Last visited

Everything posted by reepblue

  1. I've spent the last 2 days working on this map. I've gotten the map to run atleast 60fps. I first implemented my Portal Volume. This is a class I've coded that turns a Brush into a volume that detects entities within it's bounds. That helped me find the main drain of the map by section as I could manually hide everything in a room if I wanted too. Next up, I merged some models, and set more stuff to use no shadows. I only saw little improvement when after doing this. My batches went down a bit, but I was still seeing 60 frames tops in that last room. I also disabled shadows on the second spotlight. I went to the other spotlight, and turns out that it's shadows being redrawn each time, regardless that all other lights are ether not being drawn, or have their shadow mode set to none. It's weird, because I thought the engine could handle a spotlight casting on a rotating fan and be fine, but it turns out that's too expensive. So I went back and re-lit the room. It's not what I intended, but I get 80-90fps in this room now. I also have a bit of volume effects on point lights to make the fan holes pop out more, but I see no performance dip having them on or off. To make up for not having a dynamic shadow, I'll take the volume effect.
  2. I don't see why not! Crazycarpet made it so it can be installed in any LE project without any issues. Nice to see that wiki getting some attention again.
  3. Ok, great. Keep in mind that I do have some things in check on my application side of things. For example, anything that has mass, automatically get's it's shadow mode set to Dynamic. From your list, I can agree I have a lot of modular bits, so I guess I can take a look at that. Can't wait for the video too. I've also just got done with my portal volume system. It basically acts like a manual area portal that collects all entities in it's volume then hides/shows them. on command. I've gain about 20fps after implementing it.
  4. Sorry, it's map den01. I was really tired when I made it, Also, that's interesting.
  5. Here it is, sorry for the delay. https://dl.dropboxusercontent.com/u/16218991/Requests/framerateissue.7z Instructions: 1. Extract the project to anywhere on your Harddrive. 2. Run "run.bat". This will launch the game (Release) in fullscreen, and devmode. (you can edit this if you want.) 3. It tilde to open the console, and enter "map den01" and press enter. 4. Once in the map, open the console again, and type in "stats 2" to show stats. 5. Waik around, and look at numbers. (The door to the hallway opens with "e".) You can also open the project in the editor. Thanks, I hope something can be found. I'm working on something that might help with this, or at least test my hypothesis,
  6. Hey all, I'm working on a map and I'm running into some slow down with my map. I did the following from past topics to get the framerate back up. I only have 3 spotlights Static+Dynamic+Buffered and anything with mass (minus debris which don't cast a shadow) have their shadows set to Dynamic. Everything else ether doesn't cast a shadow or is static. Everything in the map has the view range of ether medium or near. I also did the automated AABB system as a test, no luck. Killing the lights with my fullbright command shoots the framerate back up. Which is why I think it's a shadow issue. I left any Occlusion Culling modes to their default settings. No volumetics. It's not my resolution as windowed mode has the same results. There is only a fog post process shader. One thing I think might be causing an expense is that I have some lamps hanging from a point by a ball joint. Batches seem to go up around to 230 in that room so I guess I can remove that. These are my settings: <?xml version="1.0"?> <settings> <display screenwidth="1024" screenheight="768" fullscreen="1" center="1" forcenativeres="1" vr="0" /> <graphics lightquality="1" multisample="1" terrainquality="1" tessellation="1" vsync="0" fov="70" /> <controls show_console="0" /> </settings> If there is anything else I can try, let me know. I'll be uploading the project after I temp fix the player input. As the new input system Matt made seems to be a bit busted. I also will have to use my mobile data so if there is any ideas, I'd like to try before I upload it. Thanks, I'll get right to uploading the project...
  7. I'm having this issue mostly with fullscreen. Windowed always seems to work.
  8. I hope you add improvements while you're back in the editor's code. Overall, really cool. Super excited for this!
  9. I recently got home and was happy to see that progress was made on this. Just plopped in the code in my test entity and it works exactly like the lua version! Really awesome, thanks Crazycarpet and Josh for helping with this. Now like if you were making a lua project, you can make animated objects without worrying about animations in C++. Really cool! This will be part of the "core" files in LEX2. Just commited the files to the dev git!
  10. Crazycarpet and I have been back and forth until 3AM EST! It's pretty much done minus an error in animation initiation and frametime. I believe that's all that needs to be fixed now. This overall is really great. Hopefully now more games will be done in C++.
  11. Interestingly, if I use the debugger and use animation->length, it'll return 46. However. getting GetAnimationLength in the loop doesn't seem to return anything. I tried a hard coded value and it made no difference.
  12. Trying to convert the animationmanager script to a C++ class. However, it's not behaving like the lua variant. It doesn't seem to find the length value, and it skips some time before animation. On top of that, restarting the map, the model is still animating. #include "../Core/base.h" #include "puppeteeranimating.h" class Animation { public: Animation() {}; virtual ~Animation() {}; long blendstart; long blendfinish; float blendtime; std::string sequence; long length; float speed; bool mode; long starttime; bool endOfSequenceReached = false; void endHook() {}; int endFrame; }; vector<Animation*> animations; AnimationManager::AnimationManager(Entity* pEntity) { if (pEntity == NULL) { Debug::Error("AnimationManager: Entity cannot be nil."); } entity = pEntity; frameoffset = Math::Random(0, 1000); } AnimationManager::~AnimationManager() { vector<Animation*>::iterator it; for (it = animations.begin(); it != animations.end(); ++it) { SAFE_DELETE(*it); } ClearAnimations(); } void AnimationManager::SetAnimationSequence(std::string pSequence, const float pSpeed, const float pBlendTime, bool pMode, void EndHook(), int pEndFrame) { // Check for redundant animation descriptor if (pMode = false) { if (animations.size() > 0) { if (animations[animations.size()]->sequence == pSequence) { if (animations[animations.size()]->speed == pSpeed) { // No change to blend time, so don't alter this? animations[animations.size()]->blendtime = pBlendTime; return; } } } } // Create new animation descriptor and add to animation stack Animation* animation = new Animation(); animation->blendstart = Time::GetCurrent(); animation->blendfinish = animation->blendstart + pBlendTime; animation->sequence = pSequence; animation->length = entity->GetAnimationLength(animation->sequence, true); animation->speed = pSpeed; animation->mode = pMode; animation->starttime = animation->blendstart; //animation->endHook = EndHook(); animation->endOfSequenceReached = false; animation->endFrame = pEndFrame; animations.push_back(animation); } void AnimationManager::ClearAnimations() { animations.clear(); } void AnimationManager::Update() { int i = 0; long blend; long frame; int n = 0; bool doanimation = false; long currenttime = Time::GetCurrent(); int maxanim = -1; //for (i; animation; animations) //{ vector<Animation*>::iterator iter = animations.begin(); for (iter; iter != animations.end(); iter++) { Animation* animation = *iter; // Lock the matrix before the first sequence is applied if (doanimation == false) { doanimation = true; entity->LockMatrix(); } // Calculate blend value blend = (currenttime - animation->blendstart) / (animation->blendfinish - animation->blendstart); blend = Math::Min(1.0, blend); if (animation->mode == false) { frame = currenttime * animation->speed + frameoffset; } else { frame = (currenttime - animation->blendstart) * animation->speed; long length = entity->GetAnimationLength(animation->sequence, true); //long length = animation->length; // If a certain frame was specified, call the hook early and remove it if (animation->endFrame != NULL) { if (frame > animation->endFrame) { //animation->endHook(); animation->endFrame = NULL; //animation->endHook = NULL; } } if (frame / 100 >= length - 1) { frame = length - 1; maxanim = i + 1; if (animation->endOfSequenceReached == false) { DevMsg("AnimationManager: endOfSequenceReached."); animation->endOfSequenceReached = true; } } } // if (animation->mode) // Apply the animation if (animation->sequence != S_NULL) { entity->SetAnimationFrame(frame, blend, animation->sequence, true); } // If this animation is blended in 100%, all previous looping animation sequences can be dropped if (blend >= 1.0) { maxanim = Math::Max(maxanim, i); } } // forloop // Unlock entity matrix if any animations were applied if (doanimation == true) { entity->UnlockMatrix(); } // Clear blended out animation - moved this out of the loop to prevent jittering if (maxanim > -1) { int index = 1; vector<Animation*>::iterator it = animations.begin(); for (it; it != animations.end(); it++) { Animation* completedanimation = *it; if (n < maxanim) { if (completedanimation->mode == false || completedanimation->endOfSequenceReached == true) { DevMsg("AnimationManager: Removing completedanimation."); animations.erase(animations.end()-index); } else { index = index + 1; } } else { break; } } } } // The test entity: PuppeteerAnimating::PuppeteerAnimating(Entity* pEntity) : Puppeteer(pEntity) { Start(); } PuppeteerAnimating::~PuppeteerAnimating() { SAFE_DELETE(animationmanager); } void PuppeteerAnimating::Start() { animationmanager = new AnimationManager(entity); } void PuppeteerAnimating::Use(Entity* pCaller) { DevMsg("use"); //animationmanager->SetAnimationSequence("Run", 0.04); animationmanager->SetAnimationSequence("Death", 0.04, 300, true); } void PuppeteerAnimating::Draw(Camera* camera) { animationmanager->Update(); } Did I convert the code correctly? I got confused with the for loops.
  13. I've started on my quest to make a full C++ has started today. I've noticed that LEX2 via the project manager didn't copy over as clean as it should, so I had to make the project from scratch which wasn't a big deal (for me). I should look into a way of getting that fixed. After setting the project up, I noticed a few errors I was getting after I commented out the LUA_GAME preprocessor. It was a quick fix, and development went under way after that. For this project, I'll need things that's already available in Lua as part of the SDK. The high priorities are the first person player, animation manager, first person weapon (the pistol) and the Crawler's AI. As I said before, I don't want to convert SDK scripts to C++, but instead write the code myself. I'll look at the Lua stuff only if I get stuck. Today I found out that not everything will work when you convert Lua code to C++. I decided on the player as I've written it for C++ with my actor class, then converted it to Lua because of problems. Now I want to but it back to C++ as a puppeteer. It took a few hours line by line converted the code. When it was all done, I ran into a few issues. First off was HOW to spawn it? I could use a puppeteer script like I mentioned in my last blog, but the player should be spawned dead last. So the best method was to create the player in LEX2's OnPostMapLoad function. // This function is called when the program finished loading a map. void OnPostMapLoad() { Entity* puppet = WORLD->FindEntity("Player"); FPSPlayer* player = new FPSPlayer(puppet); } This function is called at the every end of the level loading process. This is mostly so we don't hear the weapon being picked up while the map is loading, or a spawn sound like the Vectronic Demo. I was then running into null values that were driving me crazy. I went back and predefined all empty values as NULL and I was still getting a crash. It turns out, I didn't have the bool function returning the right value. Next was the footstep sounds. As I said before, I copied my fully working Lua player script and I noticed that the footstep sounds were playing too fast. I defined the value lastfootsteptime as an int in the header as 0, but when I did a system print of that value, it'd always return as 1. the fix was to define the variable before the footstep function instead of in the header as so: int lastfootsteptime = 0; void FPSPlayer::UpdateFootsteps() { if (lastfootsteptime == NULL) { lastfootsteptime = 0; } // If we're moving and not in the air, play a step sound. if (input[0] != 0 || input[1] != 0) { float speed = entity->GetVelocity().xz().Length(); if (entity->GetAirborne() == false) { if (speed > MoveSpeed*0.5) { long t = Time::GetCurrent(); long repeatdelay = 500; if (t - lastfootsteptime > repeatdelay) { lastfootsteptime = t; PlayFootstepsSound(); } } } } } Last, I had to fix a Gimbal lock with picked up objects. This was because all variables in Lua and C++ work differently. So when going the lines one by one, I stored rotation values in a Vec3, and not a Quat. After the first day of my summer game, I got a player that walks around, jumps, can crouch under tight spaces with working sounds! I just got a few things to tweak before going to the next thing which will probably be the animation manager.
  14. reepblue

    Status Report

    The Source engine has a demo system which records players actions in a small file. I might implement a system so demos record automatically for the next update.
  15. reepblue

    Status Report

    I only plan to meet up with you Josh (If you want) and a few Valve employees to talk about Steamworks and Source engine stuff. If I don't get a chance to, I can do so when/if I go to their HQ. I'm talking to Jeep about scheduling a visit while I'm there there. (I'm flying across the ocean, might as well.) If I don't get to talk to Gabe at the event, I can always do it then. I want to get some shirts done, I know a place where I can do it on the cheap. I talked about it with my other team members but they got the idea that we'd look like some MLG gaming team. Still out to lunch with it. It also depends on finances. We're kind of all penny pinching. I might need to borrow one although I don't work for Leadwerks Software.
  16. I wanted to give you an update since this blog post and let you know how well (or not) I'm following those plans. Blue Portals: Anniversary Edition (Skip this if you don't care..) Sunday I pushed a long over due push to Steam for beta testers to play and give feedback. I don't like to push to Steam often as my connection isn't that strong so any uploads bigger then a few megabytes causes an upload failure, I usually split updates into multiple pushes to prevent such problems but sometimes you have to push one large file that'll cause a error. This time I instead used my unlimited 4G mobile data and I had way better luck, and will be using this method from now on. We right now only have a small handful of testers and I wish to keep it that way for a little while longer. It's interesting to see the same play-tester play the same map in different updates regardless if anything changed. There was one map where no reports or issues where given from this tester last update. I barely changed the room, and this time they informed me that something felt impossible to achieve. I also keep play-testers out of developer news. This way I can introduce something brand new to them and they can report back if they understood it and/or liked the idea. I really wish I was in a position to watch people using Steam's broadcasting service, but I think even with my mobile data, it'd be unwatchable due to the high ping that wireless services have. Although I wished the teaser trailer was done last month, I'm happy to report that it's being worked on now. I've got a message this morning that the recording is done. It just needs to be edited and such. Really cool as the mod has a look and feel that we're happy with. I guess it's better that the stuff got recorded today than a month ago as a month ago some models still had their ambient occlusion maps for skins! Overall, the mod is coming together very nicely. There are a few things I'm worried about but I'm sure time will allow me to answer more questions I have. I'll keep you posted on this as I see it as a major stepping stone. LEX2 A few hours ago, I pushed a near final build of it. In-short, I've cleaned up the code, deleted useless classes and changed how somethings operate. For example, LEX2 has this function called AssetManager:PrecacheGlobal(path) which you call when you want something to be pre-loaded in memory so your game can load it later without a hitch. This was done by calling AssetManager:PrecacheGlobal(path) in App:Start() and what it did was load those paths into a list. Then when ever the world loaded a new map, PrecacheList was called which loaded every asset in that list. Although you only needed to define the asset once, it still needed to be loaded multiple times! In this blog, Josh mentioned that it's possible to load assets into one world and have it just sit in memory while your game world is active. I decided to try this, but I was careful to prevent two worlds from being current at the same time. First, I retired the old PrecacheList and made a new function. void AssetManager::PrecacheJunkyard() { DevMsg("AssetManager: Creating Junkyard."); // Save the current world if we have one. World* oldworld = WORLD; junkyard = World::Create(); World::SetCurrent(junkyard); // Precache global objects. std::list<std::string>::iterator it; for (it = precache_list.begin(); it != precache_list.end(); ++it) { if (it->c_str() != S_NULL) { AssetManager::Precache(it->c_str()); } } // Go back to the 'real' world if there was one. if (oldworld != NULL) { World::SetCurrent(oldworld); } else { World::SetCurrent(NULL); } } This will load all the assets in the list that PreacheList used into a different world than the game. Then if there is ever the chance that a world exists when the junkyard world is created, it'll go back to it. To prevent that ever happening though, I made this function not exposed to Lua and have it called at the very end of App::Start() in C++. bool App::Start() { //Create a window windowmanager.CreateWindow(System::AppName); // Create a context contextmanager.CreateContext(); ... #ifdef LUA_GAME // Finally, test the app script if (ScriptApp::Start() == false) { #ifdef WIN32 MessageBox(NULL, "Error: Failed to execute App script!", "Critical Error!", MB_OK | MB_IConstop); //MB_ICONWARNING #endif return false; } #else if (GAME::Start() == false) { return false; } #endif ... // If the user preached anything in App:Start() or GAME::Start(), load them in another world. // The Junkyard world will keep those entities in memory. AssetManager::PrecacheJunkyard(); ... return true; } So then your Lua script will look like this function App:Start() AssetManager:PrecacheGlobal("Models/Characters/hitbox.mdl") AssetManager:PrecacheGlobal("Models/Junk/cinderblock.mdl") return true end But wait! What if you want the game to automatically launch a map? I didn't want a conflict where a world would exist, and then another world gets created to spawn assets. For safety measures, I just made a PostStart() function for Lua, and have it called after AssetManager::PrecacheJunkyard(). { ..... // If the user preached anything in App:Start() or GAME::Start(), load them in another world. // The Junkyard world will keep those entities in memory. AssetManager::PrecacheJunkyard(); #ifdef LUA_GAME ScriptApp::PostStart(); #else GAME::PostStart(); #endif return true; } -- This function will be called right after when the program starts. function App:PostStart() end I really didn't test what would happen if I did load a map before AssetManager::PrecacheJunkyard(). I assume there would be a pause, as the worlds get swapped around, but I'm a bit too scared to try.. but also kind of curious... I've also sorted the filesytem. Everything LEX2 is within Source/Core with one cpp file looking like this. // $PROJECT_NAME_main.cpp. #include "Core/base.h" #ifndef LUA_GAME namespace GAME { // This function will be called once when the program starts. bool Start() { return true; } // This function will be called right after when the program starts. void PostStart() { } // This is our main program loop and will be called continuously until the program ends. bool Loop() { return true; } // This function is called when the program is loading a map. (This is where you draw your loading screen!) void OnMapLoad() { } // This function is called when the program is called to pause. void onpause() { } // This function is called when the program is called to resume. void onresume() { } // This function is called when the program finished loading a map. void OnPostMapLoad() { } // This function is called when the program disconnected from a map. void OnDisconnect() { } // This function is called when the program closes. void OnShutdown() { } // C++ function only. This is how you link editor entities to your C++ classes void LoadEntity(Entity* entity) { /* // Attach loaded entites to puppeteers. // This can get long and messy, there is some talk about this getting auto-generated with an offical actor class. // Cross your figners for that day.... Puppeteer* puppeteer = NULL; if (entity->GetKeyValue("puppeteer") == "Rocket") { puppeteer = new Rocket(entity); } else if (entity->GetKeyValue("puppeteer") =="Demon") { puppeteer = new Demon(entity); } else if (entity->GetKeyValue("puppeteer") =="Portal") { puppeteer = new Portal(entity); } */ } } #endif // !LUA_GAME As you can see, it's pretty much exactly like App.lua. If LUA_GAME isn't defined, it calls this code instead of the App.lua file. I did this to make making a game for C++ and Lua very similar. There is a function that gets called within the MapHook to link entities to the Puppeteer class which can be linked with one script. Script.puppeteername="" --choiceedit "Puppeteer" "foo,boo" function Script:Start() -- Attach us to a C++ class like this! self.entity:SetKeyValue("puppeteer",puppeteername) end -- There needs to be a better way of flowgraphing with C++ classes!! function Script:User1()--in self.component:CallOutputs("User1") end function Script:User2()--in self.component:CallOutputs("User2") end function Script:User3()--in self.component:CallOutputs("User3") end function Script:User4()--in self.component:CallOutputs("User4") end Summer Games Tournament As I stated, I much want to participate in this one. I don't really have much time to make a unique piece, but I want something to stress test LEX2 and see if it can be used easily and effectively. I'm thinking about my take on the AI and Events map from the Advanced First-Person Shooter Template. That map kind of bothers me as the scaling is all wacky (It was made when the editor used Meters) and I feel that it's in the one person team field of difficulty. Seems easy, where's the challenge? Well, While the end result will be a revision, I want to remodel most assets and code the entire game in C++ using LEX2's puppeteer system! I also will be coding things to my preferences so it's not like I'm just gonna convert existing Lua code to C++. I had other ideas but this seems like the best one currently. It should be an interesting project, and I'll open-source it when I'm done. Anything I make will be available for others to use in the future. I wish to start tomorrow; or when I wake up as it's past midnight. Steam Dev Days I'm making arrangements to go to Steam Dev Days this year. I've bought my ticket and I just got a few things to iron out with traveling, hotel, and some company naming conflict. My overall goal is to talk to network with other people, talk about developing games, and learn new things. I'm really stoked about the entire thing. That's all for now, wish me luck!
  17. You could use window->Active();
  18. reepblue

    Water

    That is meant for using water in small areas. If you want like an ocean or something, use set the water mode to true in the world properties.
  19. reepblue

    Widget Progress

    Really awesome! Once the full release comes out, I'm totally gonna revamp my developer console with the new GUI system!
  20. reepblue

    Lua or C++?

    Through out the Leadwerks community you'll find two types of users. You'll find a large portion of the community using lua, and a small dosage of them using C++. This makes sense as people are more often going to purchase Leadwerks without any DLCs (including the Professional Edition), and get into developing. From experience, Leadwerks at the moment puts it's primary focus on Lua scripts with it's script editor and debugger, flowgraph editor, and the script property system. Everything is pretty straight forward and it's quick and easy to prototype and develop your games. Throw in an entity in the editor, attach a script to it, adjust some values, set up connections and you're done! You'll also find a smaller chunk of the user base talking about C++. Unfortunately.as of writing this blog post, a life of a C++ user is more difficult. For one thing, we don't have any connection with the editor so any entitys we want to put in our game need to be done during run time. If you made this cool monster in C++, you'd also need to make a system so your level designers (or you) can place them in the levels. Some examples of this is people using editor placed pivot's names as spawn markers. And even if then, you'd have to make a Lua script for that pivot to send any custom/modifiable values or special events to the C++ class. Not to mention, you'll need to search around how to communicate both languages together. And if people are suborn about learning Lua, they'll end up making systems that conflict with existing features/editor Things get messy fast when making gameplay with C++. Ok, so why do we bother then? While Lua is an ideal choice for gameplay, but what about the rest of your game? You still need to control how your window, context and world handles, how user settings get applied, and a lot other gross stuff that goes into a game. You can use Lua for that, but you'll run into two issues. For one, if you're working with a team, you'll have to trust them not to touch anything relating to the under the hood stuff unless they know what they are doing. You'll also have that paranoia of slow down due to using Interpreter for everything. You'll need a lot of script logic to cause any slow down, but who knows what you're doing when it comes to the background stuff. My solution is easy, use both together! My application Leadwerks Extended Executable is designed to handle all the yucky bits in the application side of things while you can use the engine as intended. All it does is instead of launching main.lua, it calls a App class which handles the window, context, and world along with reading user settings. As of version 2, you can communicate to the C++ classes in Lua with the AppManager Class -- This line will spam We're Connected" if we're in a map. if AppManager:IsConnected() then System:Print("We're Connected") end All the guts are "locked out" for the rest of the team so you don't need to worry about Mike from the art department accidentally touching the window handling system, and setting the project back a few weeks. LEX2 also has 2 classes to accommodate for C++ gameplay classes, Actors, and Puppeteers. Puppeteers act like a Lua script. You attach an entity to the class and write the code like if you were writting a Lua Script. We're still lacking an efficient way to connect an editor entity to a class. I tried to use a Lua script, but due to the fact you'd need a script per puppeteer for it's custom values and flowgraph support, you might as well just write the damn code in Lua and be done! #if !defined( PUPPETEER_H ) #define PUPPETEER_H #pragma once #include "base.h" namespace Leadwerks { // Puppeteer's are pretty much the C++ version of lua scripts. // While using this class, keep note that this class doesn't exist in the game world. class Puppeteer : public Object { public: Puppeteer(Entity* pEntity); virtual ~Puppeteer() {}; virtual void Start() {}; virtual void PostStart() {}; virtual void Collision(Entity* pEntity, float* position, float* normal, float speed) {}; virtual void Draw(Camera* camera) {}; virtual void DrawEach() {}; virtual void PostRender(Context* context) {}; virtual void UpdateMatrix() {}; virtual void UpdatePhysics() {}; virtual void UpdateWorld() {}; void Detach(); void RemoveAll(); Entity* GetPuppet() { return entity; } Entity* entity; // The entity we'll be controlling. Was gonna rename this to 'puppet', but I want programing Puppeteer classes to be the same as scripting in lua. // We can get script values like this. bool GetBoolValue(std::string pValve) { return entity->GetBool(pValve); } float GetFloatValue(std::string pValve) { return entity->GetFloat(pValve); } int GetIntValue(std::string pValve) { return static_cast<int>(entity->GetFloat(pValve)); } std::string GetStringValue(std::string pValve) { return entity->GetString(pValve); } protected: static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); static void DrawHook(Entity* entity); static void DrawEachHook(Entity* entity); static void PostRenderHook(Entity* entity); static void UpdateMatrixHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; } #endif //PUPPETEER_H There are also Actors. Unlike how Puppeteers work in which you assign an entity to it, this time you're building on top of the object. and it exists in the world. It's only really good for players, but I ran into a pickle recently where the player would not spawn in the position I tell it to. I ended up translating the entire code to Lua and it works as intended. with the bonus of the flowgraph mind you. #if !defined( ACTORS_H ) #define ACTORS_H #pragma once #include "base.h" namespace Leadwerks { // Actors are the entites, but behaving like it's under a lua script or Puppeteer. // Unlike scripts or Puppeteers, this class was ment to be the base of controlling the ACTUAL entity, without a middle class. class PivotActor : public Pivot { public: PivotActor(Entity* parent = NULL); virtual ~PivotActor(); virtual void Collision(Entity* entity, float* position, float* normal, float speed) {}; virtual void Draw(Camera* camera) {}; virtual void DrawEach() {}; virtual void PostRender(Context* context) {}; virtual void UpdateMatrix() {}; virtual void UpdatePhysics() {}; virtual void UpdateWorld() {}; protected: static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); static void DrawHook(Entity* entity); static void DrawEachHook(Entity* entity); static void PostRenderHook(Entity* entity); static void UpdateMatrixHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; class ModelActor : public Model { public: ModelActor(std::string pPath, Entity* parent = NULL); virtual ~ModelActor(); virtual void Collision(Entity* entity, float* position, float* normal, float speed) {}; virtual void Draw(Camera* camera) {}; virtual void DrawEach() {}; virtual void PostRender(Context* context) {}; virtual void UpdateMatrix() {}; virtual void UpdatePhysics() {}; virtual void UpdateWorld() {}; protected: static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); static void DrawHook(Entity* entity); static void DrawEachHook(Entity* entity); static void PostRenderHook(Entity* entity); static void UpdateMatrixHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; class CameraActor : public Camera { public: CameraActor(Entity* parent = NULL); virtual ~CameraActor(); virtual void Collision(Entity* entity, float* position, float* normal, float speed) {}; virtual void Draw(Camera* camera) {}; virtual void DrawEach() {}; virtual void PostRender(Context* context) {}; virtual void UpdateMatrix() {}; virtual void UpdatePhysics() {}; virtual void UpdateWorld() {}; protected: static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); static void DrawHook(Entity* entity); static void DrawEachHook(Entity* entity); static void PostRenderHook(Entity* entity); static void UpdateMatrixHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; // TODO: Maybe make a SpriteActor? } #endif //ACTORS_H It was kind of hard writing this entry as I work with both languages. I guess the overall message is to chose you're battles and do what's in your skill set and preferences. I'd still love there to be an easy way to code gameplay elements in C++ like I do with Source. The class hierarchy system really comes in handy as you can just make a bunch of base classes and build off of them as needed. Hopefully, this will get addressed soon. In-fact, I actually made this blog post in reflection of this forum post. Maybe someday we can make our games fully in C++ and have access to the flowgraph editor and to be able to set custom properties!
  21. You took my idea(s). [1] [2] Joking aside, this would be great. I just ask for a proper way of spawning said objects into the editor and flowgraph communication support! I'd love to code gameplay stuff in C++ without the gotcha's it has now. I actually created a player C++ side but then noticed the system to spawn the entity at a fixed location broke somehow, so I had to translate the entire code to lua. The hook systems are confusing and I only just figured out how to use them a few months ago. I'd say go with it. I'd love for C++ side of things to get some attention as it feels like a "use at your own risk" feature.
  22. This should do it, didn't test it, but should work. animatedtrans.zip
  23. There is some commented code int he shader, but it only looks decent if a lot of MSAA is applied. I hope this get's addressed at some point.
  24. That reminded me a lot of Source's projected texture entity. For Portal 2, Valve made light masks to cast interesting shadows on top of the ruins of Aperture Science. And since all of Source's lights are baked, they were a scapegoat for dynamic shadows for doors and such. The entity can do so much more that lightmasks, but that's mostly what Valve used them for. The flashlight in HL2 is another example. I recall Josh mentioning something relating to this in a hangout, or I must of dreamt it. Would be cool, seems like it will work well with the current render.
×
×
  • Create New...