Skip to content

Commit 8f7b8fb

Browse files
committed
👼Script: Added OGRE shader parameter bindings + example ✨
// New Script API: // -- `BeamClass.getManagedMaterialNames()` -> `array<string>@` // -- `BeamClass.getManagedMaterialInstance()` -> `Ogre::MaterialPtr` // -- `Ogre::Pass.__getNamedConstants()` -> `array<string>@` // -- `Ogre::Pass.getFragmentProgramParameters()` -> `Ogre::GpuProgramParametersPtr` New internal API, `class Actor`: - getManagedMaterialInstance(const std::string& orig_name); --> Ogre::MaterialPtr - getManagedMaterialNames(); --> std::vector<std::string>
1 parent d829de5 commit 8f7b8fb

File tree

8 files changed

+155
-18
lines changed

8 files changed

+155
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/// \title Managed material diag demo
2+
/// \brief List actor's managedmats and edit shader params
3+
//
4+
// API ON DISPLAY:
5+
// -- `BeamClass.getManagedMaterialNames()` -> `array<string>@`
6+
// -- `BeamClass.getManagedMaterialInstance()` -> `Ogre::MaterialPtr`
7+
// -- `Ogre::Pass.__getNamedConstants()` -> `array<string>@`
8+
// -- `Ogre::Pass.getFragmentProgramParameters()` -> `Ogre::GpuProgramParametersPtr`
9+
// ===================================================
10+
11+
// We can't reaad from `Ogre::GpuProgramParametersPtr` at the moment :/
12+
dictionary knownConstantValues;
13+
14+
void frameStep(float dt)
15+
{
16+
BeamClass@ playerActor = game.getCurrentTruck();
17+
if (@playerActor == null)
18+
{
19+
ImGui::Text("you are on foot.");
20+
ImGui::Text("enter a vehicle to view it's managedmaterials.");
21+
return;
22+
}
23+
24+
array<string>@ managedMatNames = playerActor.getManagedMaterialNames();
25+
ImGui::TextDisabled("you're driving: "); ImGui::SameLine(); ImGui::Text(playerActor.getTruckName());
26+
ImGui::Separator();
27+
28+
for (uint iMat = 0; iMat < managedMatNames.length(); iMat++)
29+
{
30+
ImGui::PushID(iMat);
31+
Ogre::MaterialPtr mat = playerActor.getManagedMaterialInstance(managedMatNames[iMat]);
32+
if (ImGui::TreeNode(managedMatNames[iMat]))
33+
{
34+
ImGui::SameLine();
35+
if (mat.isNull()) { ImGui::TextDisabled("null"); continue; }
36+
if (mat.getTechniques().length() < 1) { ImGui::TextDisabled("no `Techniques` in mat");ImGui::TreePop(); continue; }
37+
Ogre::Technique@ matTech = mat.getTechniques()[0];
38+
if (matTech.getPasses().length() < 1) { ImGui::TextDisabled("no `Passes` in mat"); ImGui::TreePop(); continue; }
39+
Ogre::Pass@ matPass = matTech.getPasses()[0];
40+
if (@matPass == null) { ImGui::TextDisabled("null `Pass #0` in mat"); ImGui::TreePop(); continue; } // paranoia
41+
Ogre::GpuProgramParametersPtr fragParams = matPass.getFragmentProgramParameters();
42+
if (fragParams.isNull()) { { ImGui::TextDisabled("no fragment shader in mat"); ImGui::TreePop(); continue; } }
43+
array<string>@ namedConstants = fragParams.__getNamedConstants();
44+
if (@namedConstants == null) { { ImGui::TextDisabled("INTERNAL ERROR - `__getNamedConstants()` returned null"); ImGui::TreePop(); continue; } }
45+
ImGui::TextDisabled("[" + namedConstants.length() + " named constants]");
46+
47+
for (uint iCon = 0; iCon < namedConstants.length(); iCon++)
48+
{
49+
ImGui::PushID(iCon);
50+
ImGui::BulletText("[" + (iCon+1) + "/" + namedConstants.length() + "]"); ImGui::SameLine();
51+
float valMin = -1.f;
52+
float valMax = 1.f;
53+
float tmpVal = float(knownConstantValues[namedConstants[iCon]]);
54+
if (ImGui::SliderFloat(namedConstants[iCon], /*[inout]*/tmpVal, valMin, valMax))
55+
{
56+
knownConstantValues[namedConstants[iCon]] = tmpVal;
57+
fragParams.setNamedConstant(namedConstants[iCon], tmpVal);
58+
}
59+
ImGui::PopID(); // iCon
60+
61+
}
62+
63+
ImGui::TreePop();
64+
} // TreeNode())
65+
66+
ImGui::PopID(); // iMat
67+
}
68+
}

source/main/physics/Actor.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -4479,6 +4479,25 @@ Replay* Actor::getReplay()
44794479
return nullptr;
44804480
}
44814481

4482+
Ogre::MaterialPtr Actor::getManagedMaterialInstance(const std::string& orig_name)
4483+
{
4484+
auto it = ar_managed_materials.find(orig_name);
4485+
if (it != ar_managed_materials.end())
4486+
return it->second;
4487+
else
4488+
return Ogre::MaterialPtr(); // null
4489+
}
4490+
4491+
std::vector<std::string> Actor::getManagedMaterialNames()
4492+
{
4493+
std::vector<std::string> names;
4494+
for (auto it = ar_managed_materials.begin(); it != ar_managed_materials.end(); ++it)
4495+
{
4496+
names.push_back(it->first);
4497+
}
4498+
return names;
4499+
}
4500+
44824501
Vector3 Actor::getNodePosition(int nodeNumber)
44834502
{
44844503
if (nodeNumber >= 0 && nodeNumber < ar_num_nodes)

source/main/physics/Actor.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,12 @@ class Actor : public RefCountingObject<Actor>
202202

203203
/// @name Subsystems
204204
/// @{
205+
VehicleAIPtr getVehicleAI() { return ar_vehicle_ai; }
206+
Ogre::MaterialPtr getManagedMaterialInstance(const std::string& orig_name);
207+
std::vector<std::string> getManagedMaterialNames();
208+
// not exported to scripting:
205209
Replay* getReplay();
206210
TyrePressure& getTyrePressure() { return m_tyre_pressure; }
207-
VehicleAIPtr getVehicleAI() { return ar_vehicle_ai; }
208211
//! @}
209212

210213
/// @name Organizational
@@ -303,6 +306,7 @@ class Actor : public RefCountingObject<Actor>
303306
std::vector<std::vector<int>> ar_node_to_beam_connections;
304307
std::vector<Ogre::AxisAlignedBox> ar_collision_bounding_boxes; //!< smart bounding boxes, used for determining the state of an actor (every box surrounds only a subset of nodes)
305308
std::vector<Ogre::AxisAlignedBox> ar_predicted_coll_bounding_boxes;
309+
std::map<std::string, Ogre::MaterialPtr> ar_managed_materials;
306310
int ar_num_contactable_nodes = 0; //!< Total number of nodes which can contact ground or cabs
307311
int ar_num_contacters = 0; //!< Total number of nodes which can selfcontact cabs
308312
wheel_t ar_wheels[MAX_WHEELS] = {};

source/main/physics/ActorSpawner.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -6819,6 +6819,8 @@ void ActorSpawner::FinalizeGfxSetup()
68196819
"Failed to load `help` material '" + m_help_material_name + "', message:" + e.getFullDescription());
68206820
}
68216821
}
6822+
6823+
m_actor->ar_managed_materials = m_managed_materials;
68226824
}
68236825

68246826
void ActorSpawner::ValidateRotator(int id, int axis1, int axis2, NodeNum_t *nodes1, NodeNum_t *nodes2)

source/main/scripting/ScriptEngine.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "OgreScriptBuilder.h"
5454
#include "PlatformUtils.h"
5555
#include "ScriptEvents.h"
56+
#include "ScriptUtils.h"
5657
#include "Utils.h"
5758
#include "VehicleAI.h"
5859

source/main/scripting/ScriptUtils.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace RoR {
3939
/// @{
4040

4141
template <typename T>
42-
AngelScript::CScriptArray* VectorToScriptArray(std::vector<T>& vec, const std::string& decl)
42+
AngelScript::CScriptArray* VectorToScriptArray(const std::vector<T>& vec, const std::string& decl)
4343
{
4444
std::string arraydecl = fmt::format("array<{}>", decl);
4545
AngelScript::asITypeInfo* typeinfo = App::GetScriptEngine()->getEngine()->GetTypeInfoByDecl(arraydecl.c_str());
@@ -48,7 +48,8 @@ AngelScript::CScriptArray* VectorToScriptArray(std::vector<T>& vec, const std::s
4848
for (AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
4949
{
5050
// Set the value of each element
51-
arr->SetValue(i, &vec[i]);
51+
T tempval = vec[i];
52+
arr->SetValue(i, &tempval);
5253
}
5354

5455
return arr;

source/main/scripting/bindings/ActorAngelscript.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#include "Actor.h"
2323
#include "AngelScriptBindings.h"
24+
#include "ScriptEngine.h"
25+
#include "ScriptUtils.h"
2426
#include "SimData.h"
2527
#include <angelscript.h>
2628

@@ -108,8 +110,12 @@ void RoR::RegisterActor(asIScriptEngine *engine)
108110
result = engine->RegisterObjectMethod("BeamClass", "void toggleCustomParticles()", asMETHOD(Actor,toggleCustomParticles), asCALL_THISCALL); ROR_ASSERT(result>=0);
109111
result = engine->RegisterObjectMethod("BeamClass", "bool getCustomParticleMode()", asMETHOD(Actor,getCustomParticleMode), asCALL_THISCALL); ROR_ASSERT(result>=0);
110112
result = engine->RegisterObjectMethod("BeamClass", "bool isLocked()", asMETHOD(Actor,isLocked), asCALL_THISCALL); ROR_ASSERT(result>=0);
113+
111114
// - subsystems (PLEASE maintain the same order as 'Actor.h' and 'doc/angelscript/.../BeamClass.h')
112115
result = engine->RegisterObjectMethod("BeamClass", "VehicleAIClassPtr @getVehicleAI()", asMETHOD(Actor,getVehicleAI), asCALL_THISCALL); ROR_ASSERT(result>=0);
116+
result = engine->RegisterObjectMethod("BeamClass", "Ogre::MaterialPtr getManagedMaterialInstance(const string &in)", asMETHOD(Actor,getManagedMaterialInstance), asCALL_THISCALL); ROR_ASSERT(result>=0);
117+
result = engine->RegisterObjectMethod("BeamClass", "array<string>@ getManagedMaterialNames()", asFUNCTIONPR([](Actor* self) -> CScriptArray*{
118+
return RoR::VectorToScriptArray(self->getManagedMaterialNames(), "string"); }, (Actor*), CScriptArray*), asCALL_CDECL_OBJFIRST); ROR_ASSERT(result>=0);
113119

114120
// - lights (PLEASE maintain the same ordering as 'Actor.h' and 'doc/angelscript/.../BeamClass.h')
115121
result = engine->RegisterObjectMethod("BeamClass", "int getBlinkType()", asMETHOD(Actor, getBlinkType), asCALL_THISCALL); ROR_ASSERT(result >= 0);

source/main/scripting/bindings/OgreAngelscript.cpp

+51-15
Original file line numberDiff line numberDiff line change
@@ -594,28 +594,27 @@ static void TimerAssignOperator(const Timer& other, Timer* self)
594594
}
595595

596596
/***GPUPROGRAMPARAMETERSPTR***/
597-
// Note: The `*SharedPtr` is a deprecated alias of `*Ptr` in OGRE 14, but it's not yet present in the version we use.
598-
static void GpuProgramParametersPtrDefaultConstructor(GpuProgramParametersSharedPtr* self)
597+
static void GpuProgramParametersPtrDefaultConstructor(GpuProgramParametersPtr* self)
599598
{
600-
new (self) GpuProgramParametersSharedPtr();
599+
new (self) GpuProgramParametersPtr();
601600
}
602601

603-
static void GpuProgramParametersPtrCopyConstructor(const GpuProgramParametersSharedPtr& other, GpuProgramParametersSharedPtr* self)
602+
static void GpuProgramParametersPtrCopyConstructor(const GpuProgramParametersPtr& other, GpuProgramParametersPtr* self)
604603
{
605-
new (self) GpuProgramParametersSharedPtr(other);
604+
new (self) GpuProgramParametersPtr(other);
606605
}
607606

608-
static void GpuProgramParametersPtrDestructor(GpuProgramParametersSharedPtr* self)
607+
static void GpuProgramParametersPtrDestructor(GpuProgramParametersPtr* self)
609608
{
610-
(self)->~GpuProgramParametersSharedPtr();
609+
(self)->~GpuProgramParametersPtr();
611610
}
612611

613-
static void GpuProgramParametersPtrAssignOperator(const GpuProgramParametersSharedPtr& other, GpuProgramParametersSharedPtr* self)
612+
static void GpuProgramParametersPtrAssignOperator(const GpuProgramParametersPtr& other, GpuProgramParametersPtr* self)
614613
{
615614
(self)->operator=(other);
616615
}
617616

618-
static bool GpuProgramParametersPtrIsNull(GpuProgramParametersSharedPtr* self)
617+
static bool GpuProgramParametersPtrIsNull(GpuProgramParametersPtr* self)
619618
{
620619
return !(self)->operator bool();
621620
}
@@ -2142,18 +2141,42 @@ void registerOgreTechnique(AngelScript::asIScriptEngine* engine)
21422141

21432142
void registerOgrePass(AngelScript::asIScriptEngine* engine)
21442143
{
2144+
int r = 0;
21452145
engine->SetDefaultNamespace("Ogre");
21462146

21472147
engine->RegisterObjectMethod("Pass", "const string& getName() const", asMETHOD(Ogre::Pass, getName), asCALL_THISCALL);
21482148
engine->RegisterObjectMethod("Pass", "TextureUnitStateArray @getTextureUnitStates()", asFUNCTION(PassGetTextureUnitStates), asCALL_CDECL_OBJFIRST);
21492149
engine->RegisterObjectMethod("Pass", "void removeTextureUnitState(uint16 index)", asMETHOD(Ogre::Pass, removeTextureUnitState), asCALL_THISCALL);
21502150

2151-
engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getVertexProgramParameters()", asMETHOD(Ogre::Pass, getVertexProgramParameters), asCALL_THISCALL);
2152-
engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getFragmentProgramParameters()", asMETHOD(Ogre::Pass, getFragmentProgramParameters), asCALL_THISCALL);
2153-
engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getGeometryProgramParameters()", asMETHOD(Ogre::Pass, getGeometryProgramParameters), asCALL_THISCALL);
2154-
engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getTessellationHullProgramParameters()", asMETHOD(Ogre::Pass, getTessellationHullProgramParameters), asCALL_THISCALL);
2155-
engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getTessellationDomainProgramParameters()", asMETHOD(Ogre::Pass, getTessellationDomainProgramParameters), asCALL_THISCALL);
2156-
engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getComputeProgramParameters()", asMETHOD(Ogre::Pass, getComputeProgramParameters), asCALL_THISCALL);
2151+
r = engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getVertexProgramParameters()", asFUNCTIONPR([](Ogre::Pass* self) -> Ogre::GpuProgramParametersPtr {
2152+
try { return self->getVertexProgramParameters(); }
2153+
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::Pass::getVertexProgramParameters()"); return Ogre::GpuProgramParametersPtr(); }
2154+
}, (Ogre::Pass*), Ogre::GpuProgramParametersPtr), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
2155+
2156+
r = engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getFragmentProgramParameters()", asFUNCTIONPR([](Ogre::Pass* self) -> Ogre::GpuProgramParametersPtr {
2157+
try { return self->getFragmentProgramParameters(); }
2158+
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::Pass::getFragmentProgramParameters()"); return Ogre::GpuProgramParametersPtr(); }
2159+
}, (Ogre::Pass*), Ogre::GpuProgramParametersPtr), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
2160+
2161+
r = engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getGeometryProgramParameters()", asFUNCTIONPR([](Ogre::Pass* self) -> Ogre::GpuProgramParametersPtr {
2162+
try { return self->getGeometryProgramParameters(); }
2163+
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::Pass::getGeometryProgramParameters()"); return Ogre::GpuProgramParametersPtr(); }
2164+
}, (Ogre::Pass*), Ogre::GpuProgramParametersPtr), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
2165+
2166+
r = engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getTessellationHullProgramParameters()", asFUNCTIONPR([](Ogre::Pass* self) -> Ogre::GpuProgramParametersPtr {
2167+
try { return self->getTessellationHullProgramParameters(); }
2168+
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::Pass::getTessellationHullProgramParameters()"); return Ogre::GpuProgramParametersPtr(); }
2169+
}, (Ogre::Pass*), Ogre::GpuProgramParametersPtr), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
2170+
2171+
r = engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getTessellationDomainProgramParameters()", asFUNCTIONPR([](Ogre::Pass* self) -> Ogre::GpuProgramParametersPtr {
2172+
try { return self->getTessellationDomainProgramParameters(); }
2173+
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::Pass::getTessellationDomainProgramParameters()"); return Ogre::GpuProgramParametersPtr(); }
2174+
}, (Ogre::Pass*), Ogre::GpuProgramParametersPtr), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
2175+
2176+
r = engine->RegisterObjectMethod("Pass", "GpuProgramParametersPtr getComputeProgramParameters()", asFUNCTIONPR([](Ogre::Pass* self) -> Ogre::GpuProgramParametersPtr {
2177+
try { return self->getComputeProgramParameters(); }
2178+
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::Pass::getComputeProgramParameters()"); return Ogre::GpuProgramParametersPtr(); }
2179+
}, (Ogre::Pass*), Ogre::GpuProgramParametersPtr), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
21572180

21582181
engine->RegisterObjectMethod("Pass", "void setVertexProgramParameters(GpuProgramParametersPtr)", asMETHOD(Ogre::Pass, setVertexProgramParameters), asCALL_THISCALL);
21592182
engine->RegisterObjectMethod("Pass", "void setFragmentProgramParameters(GpuProgramParametersPtr)", asMETHOD(Ogre::Pass, setFragmentProgramParameters), asCALL_THISCALL);
@@ -2290,6 +2313,19 @@ void registerOgreGpuProgramParameters(AngelScript::asIScriptEngine* engine)
22902313
catch (...) { App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::GpuProgramParameters::setNamedConstant(string, array<color>)"); }
22912314
}, (GpuProgramParametersPtr const&, const std::string&, CScriptArray*), void), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
22922315

2316+
r = engine->RegisterObjectMethod("GpuProgramParametersPtr", "array<string>@ __getNamedConstants()", asFUNCTIONPR([](GpuProgramParametersPtr const& self) -> CScriptArray* {
2317+
try {
2318+
std::vector<std::string> keys;
2319+
const Ogre::GpuNamedConstants& namedConstants = self->getConstantDefinitions();
2320+
for (auto& pair : namedConstants.map)
2321+
keys.push_back(pair.first);
2322+
return RoR::VectorToScriptArray(keys, "string");
2323+
}
2324+
catch (...) {
2325+
App::GetScriptEngine()->forwardExceptionAsScriptEvent("Ogre::GpuProgramParameters::__getNamedConstants()");
2326+
return nullptr; }
2327+
}, (GpuProgramParametersPtr const&), CScriptArray*), asCALL_CDECL_OBJFIRST); ROR_ASSERT(r >= 0);
2328+
22932329

22942330
r = engine->SetDefaultNamespace(""); ROR_ASSERT(r >= 0);
22952331
}

0 commit comments

Comments
 (0)