-
Posts
24,625 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by Josh
-
Oh sorry, in that case the script you need will be in the Scripts/Objects/Player folder.
-
It will be in Source/Components/Player, in a new Lua project. We are also currently working on a first-person shooter template, to be released in five weeks.
-
0.9.8 Added prefab breaking in editor. I think the user interface is a little strange, but it works correctly. Using BC7 for probe specular maps, when possible. Most scene files that use a lot of probes will be about 8x smaller in size. Added right-click "Select" menu on group nodes in scene browser, to select all entities in the group and sub-groups.
-
Okay, so here is what is happening: The first time LoadPrefab is called in the scene load routine, the prefab file is loaded, and the Load method is run. The prefab stores the loaded entity in a NULL world, and then makes an instance of it and returns that instance. Every time LoadPrefab is called after that, and it detects the path is the same as the first call, another instance is of the prefab entity is returned. At the end of the LoadScene routine, each component in each entity in the scene has its Load method called. So three entities coming from one prefab means it is called once when the prefab is loaded, and then once for each entity in the scene. Perhaps the Load method should be skipped for prefabs in the scene, because that data is all supposed to come from the prefab. In that case, the Load method would be called once, and the Copy method would be called three times.
-
What shader family does your material use? Can you upload your material and texture and I will try it?
-
You also have the option to pass an extra object info the scene load function, which will be passed to each call of Component::Load. You could store the framebuffer there, or create your own class that stores all your game variables like this: struct MyGameStuff : public Object { shared_ptr<Window> window; shared_ptr<Framebuffer> framebuffer; table settings; };
-
Make sure you check to see if ActiveWindow returns NULL. It will not return a window if the window is not selected.
-
0.9.8 Project manager will now move the most projects to the top of the list when you switch to them.
-
Code for loading VR pose data from SteamVR (converting it into JSON files) table t; auto stream = ReadFile(GetPath(PATH_DESKTOP) + "/R_BONE_ROTATIONS.txt"); t = {}; while (not stream->Eof()) { String s = stream->ReadLine(); s = s.Replace("x:", ""); s = s.Replace("y:", ""); s = s.Replace("z:", ""); s = s.Replace("w:", ""); s = s.Replace("-", ""); s = s.Replace("{", ""); s = s.Replace("}", ""); s = s.Replace(" ", ""); auto sarr = s.Split(","); table r = {}; for (int n = 0; n < sarr.size(); ++n) r[n] = sarr[n].ToFloat(); t.push_back(r); } SaveTable(t, StripExt(stream->path) + ".json");
-
I don't think there is any way to get finger tracking data from Knuckles controllers without using Valve's horrible action manifest system.
-
0.9.8 Updates to VR controller input. Hmd and VrController classes now have a name member indicating what the device is. Added Entity::Collide method with several useful overloads.
-
Okay, no big surprises here, but I noted some small details. It does not appear to be possible to retrieve the Index finger orientations with the original OpenVR interface. I will look into this next.
-
This is the code the editor uses to read JSON component files and create the interface. for (int n = 0; n < j3["component"]["properties"].size(); ++n) { Vec3 range = Vec3(NAN); options.clear(); WString name, label, pattern, filepath; int type = 0; int style = 0; if (not j3["component"]["properties"][n].is_object()) continue; if (j3["component"]["properties"][n].is_number_unsigned()) style = j3["component"]["properties"][n]; name = std::string(j3["component"]["properties"][n]["name"]); if (j3["component"]["properties"][n]["label"].is_string()) label = std::string(j3["component"]["properties"][n]["label"]); switch (j3["component"]["properties"][n]["value"].type()) { case nlohmann::json::value_t::null: type = PROPERTY_OBJECT; style = TEXTFIELD_READONLY; break; case nlohmann::json::value_t::number_integer: case nlohmann::json::value_t::number_unsigned: style = SPINNER_INTEGER; type = PROPERTY_NUMBER; if (j3["component"]["properties"][n]["options"].is_array()) { style = 0; type = PROPERTY_OPTION; for (int k = 0; k < j3["component"]["properties"][n]["options"].size(); ++k) { if (j3["component"]["properties"][n]["options"][k].is_string()) { std::string s = j3["component"]["properties"][n]["options"][k]; options.push_back(s); } } } break; case nlohmann::json::value_t::number_float: style = SPINNER_FLOAT; type = PROPERTY_NUMBER; /*if (j3["component"]["properties"][n]["range"].is_array() and j3["component"]["properties"][n]["range"].size() == 2) { if (j3["component"]["properties"][n]["range"][0].is_number() and j3["component"]["properties"][n]["range"][1].is_number()) { } }*/ break; case nlohmann::json::value_t::string: type = PROPERTY_STRING; style = TEXTFIELD_LOSEFOCUSACTIONEVENT | TEXTFIELD_ENTERKEYACTIONEVENT; if (j3["component"]["properties"][n]["filecategory"].is_string()) { style = 0; type = PROPERTY_FILE; std::string cat = j3["component"]["properties"][n]["filecategory"]; if (cat == "SOUND") { pattern = GetFilePattern(FILECATEGORY_SOUND); filepath = "Sound/"; } else if (cat == "MODEL") { pattern = GetFilePattern(FILECATEGORY_MODEL); filepath = "Models/"; } else if (cat == "MATERIAL") { pattern = GetFilePattern(FILECATEGORY_MATERIAL); filepath = "Materials/"; } else if (cat == "TEXTURE") { pattern = GetFilePattern(FILECATEGORY_TEXTURE); filepath = "Materials/"; } else if (cat == "PREFAB") { pattern = GetFilePattern(FILECATEGORY_PREFAB); filepath = "Prefabs/"; } } else if (j3["component"]["properties"][n]["filepattern"].is_string()) { style = 0; type = PROPERTY_FILE; pattern = std::string(j3["component"]["properties"][n]["filepattern"]); } break; case nlohmann::json::value_t::boolean: type = PROPERTY_BOOLEAN; break; case nlohmann::json::value_t::array: switch (j3["component"]["properties"][n]["value"].size()) { case 2: type = PROPERTY_VECTOR2; break; case 3: type = PROPERTY_VECTOR3; if (j3["component"]["properties"][n]["type"].is_string() and j3["component"]["properties"][n]["type"] == "COLOR") { type = PROPERTY_COLOR; style = COLOREDIT_RGB; } break; case 4: type = PROPERTY_VECTOR4; if (j3["component"]["properties"][n]["type"].is_string() and j3["component"]["properties"][n]["type"] == "COLOR") { type = PROPERTY_COLOR; style = COLOREDIT_RGBA; } break; default: continue; } break; default: continue; } c.varnames[label] = name; c.values[name] = j3["component"]["properties"][n]["value"]; if (j3["component"]["properties"][n]["style"].is_number_unsigned()) style = j3["component"]["properties"][n]["style"]; auto g = c.propertygroup->AddProperty(label, PropertyType(type), style); if (type == PROPERTY_OPTION) { for (auto s : options) { g->widget->AddItem(s); } } if (type == PROPERTY_FILE) { g->widget->As<PathEdit>()->SetPattern(pattern); g->widget->As<PathEdit>()->defaultpath = filepath; } if (type == PROPERTY_OBJECT) { Listen(EVENT_WIDGETACTION, g->button); } g->id = name; }
-
This is what I figured out. const int INDEX_BUTTON_B = 1; const int INDEX_BUTTON_A = 2;// also squeeze handle const int INDEX_BUTTON_DPAD = 32;// also touchpad button const int INDEX_BUTTON_TRIGGER = 33; const int INDEX_AXIS_DPAD = 0;// this is also the touchpad const int INDEX_AXIS_TRIGGER = 1; const int VIVE_BUTTON_TOUGHPAD = 32; const int VIVE_BUTTON_TRIGGER = 33; const int VIVE_BUTTON_MENU = 1; const int VIVE_BUTTON_GRIP = 2; const int VIVE_AXIS_TOUCHPAD = 0; const int VIVE_AXIS_TRIGGER = 1;// x axis only More info: https://www.vive.com/hk/support/vive-pro-hmd/category_howto/about-the-controllers.html This is the code I am using to test: #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CLIENTCOORDS | WINDOW_CENTER | WINDOW_TITLEBAR); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a world auto world = CreateWorld(); //Get the VR headset auto hmd = GetHmd(world); //Environment maps auto specmap = LoadTexture("https://github.com/UltraEngine/Assets/raw/main/Materials/Environment/footprint_court/specular.dds"); auto diffmap = LoadTexture("https://github.com/UltraEngine/Assets/raw/main/Materials/Environment/footprint_court/diffuse.dds"); world->SetEnvironmentMap(specmap, ENVIRONMENTMAP_BACKGROUND); world->SetEnvironmentMap(specmap, ENVIRONMENTMAP_SPECULAR); world->SetEnvironmentMap(diffmap, ENVIRONMENTMAP_DIFFUSE); //Add a floor auto floor = CreateBox(world, 5, 1, 5); floor->SetPosition(0, -0.5, 0); auto mtl = CreateMaterial(); mtl->SetTexture(LoadTexture("https://github.com/UltraEngine/Documentation/raw/master/Assets/Materials/Developer/griid_gray.dds")); floor->SetMaterial(mtl); const int INDEX_BUTTON_B = 1; const int INDEX_BUTTON_A = 2;// also squeeze handle const int INDEX_BUTTON_DPAD = 32;// also touchpad button const int INDEX_BUTTON_TRIGGER = 33; const int VIVE_BUTTON_TOUGHPAD = 32; const int VIVE_BUTTON_TRIGGER = 33; const int VIVE_BUTTON_MENU = 1; //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { bool change = false; //Test axes float tol = 0.01f; for (int n = 0; n < 64; ++n) { for (int k = 0; k < 2; ++k) { if (hmd->controllers[k]) { auto v = hmd->controllers[k]->GetAxis(VrControllerAxis(n)); if (Abs(v.x) > tol or Abs(v.y) > tol) { window->SetText("Axis " + String(n) + ": " + String(v.x) + ", " + String(v.y)); change = true; break; } } } } // Check buttons for (int n = 0; n < 64; ++n) { for (int k = 0; k < 2; ++k) { if (hmd->controllers[k] and hmd->controllers[k]->ButtonDown(VrControllerButton(n))) { window->SetText("Button: " + String(n)); change = true; } } } if (not change) window->SetText(""); world->Update(); world->Render(framebuffer); } return 0; }
-
0.9.8 Added a VR game template. There's not much in there, but I wanted to get it started. Fixed some layout issues in the project creation dialog.
-
0.9.8 glTF to model batch conversion will now automatically convert all model textures to DDS, or use the existing DDS files if they are already there and newer than the PNG/JPEG images.
-
It could also be possible to make the particle count automatically calculated and hidden from the user, and it would just adjust to whatever the settings required.
-
I will add this member in the next build: std::array<Plane, 6> camerafrustum;
-
0.9.8 Added particle emission shape and area, in the editor only. The editor itself can be run as a script execution tool now. If you pass a string parameter to the command line, the editor will execute the specified script and exit, without initializing the whole editor. Keep in mind this will only include the pure Ultra API, not the extended editor API. Editor.exe +script "Scripts/Myscript.lua"
-
Duration is a function of the particle count, burst quantity, and emission frequency. I just added emitter shapes for box and ellipsoid, including area. The scale beginning and end is in the radius properties, although I think that should be renamed. Alpha is automatic. I was not planning on the graph mechanism for scale and alpha that Leadwerks uses, because I think it is overcomplicated and I never saw it getting used.
-
Ah, okay, so like per-camera compute.
-
Okay, I am just hitting "New Game" and leaving the camera in the starting area: With fog: 240 Without fog: 253 Not a huge difference, so I will look at some other things and see what has the biggest impact.
-
I am testing your latest build on a GEForce 1080 at 1920x1080 resolution. Framerate is about 240. Is there a simple way to disable the fog boxes?
-
This is available now in 0.9.8 beta.