-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
👼Script:
Ogre::ManualObject
API - create manual mesh
2 new example scripts. New script API: * `enum Ogre::RenderOperation` * `class Ogre::ManualObject` REF | NOCOUNT object type. This is castable to MovableObject. Official tutorial for Ogre::ManualObject: https://ogrecave.github.io/ogre/api/latest/manual-mesh-creation.html * Functions in OGRE SceneManager: `createManualObject()`, `getManualObject()`, `destroyManualObject()` * Extra feature: function `TerrainClass::getHeightAt()` for the MeshedConcrete example to work.
- Loading branch information
Showing
5 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
RIGS OF RODS - bundled scripts | ||
============================== | ||
|
||
TIP: you can run any script in game using 'loadscript' command in the console. To display console, press '~' anytime or in simulation go to top menu > Tools > Show console. | ||
|
||
FOR DEVELOPERS: Visit https://developer.rigsofrods.org/ and click "Script-side APIs" link on main page for detailed docs. | ||
|
||
Conventions: | ||
* Scripts named 'example_*.as' are short introductory scripts that perform one thing, usually showing UI with tips and controls. You can run them using 'loadscript'. | ||
* Scripts named '*_editor.as' are complete tools. You can run them using 'loadscript'. | ||
* Scripts named '*_utils.as' are includes - running them directly is not possible, 'loadscript' would result in error "there is no main() function". | ||
|
||
Special scripts: | ||
* 'default.as' - fallback terrain script, loaded if modder didn't provide custom script. | ||
* 'base.as' - an include script for terrain, handles some basic object events. | ||
* 'races.as' - an include script for terrain, implements waypoint-based driving challenges. | ||
* 'AI.as' - a backend script for the "Vehicle AI" menu in top menubar. Spawns an AI-driven vehicle, as configured in the menu. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// \title example - OGRE - ManualObject | ||
// \brief shows how to make custom mesh and place it to scene | ||
// =================================================== | ||
|
||
|
||
array< Ogre::ManualObject@ > gManualObjects; | ||
Ogre::SceneNode@ gGroupingSceneNode = game.getSceneManager().getRootSceneNode().createChildSceneNode(makeID("")); | ||
|
||
string makeID(string name) | ||
{ | ||
// to avoid clash with leftover scene nodes created before, we include the NID in the name - using automatic global var `thisScript`. | ||
return "example-OGRE-ManuaObject.as(NID:"+thisScript+"): "+name; | ||
} | ||
|
||
Ogre::ManualObject@ makePlane(string meshName, string matName) | ||
{ | ||
Ogre::ManualObject@ mo = game.getSceneManager().createManualObject(meshName); | ||
mo.begin(matName, Ogre::OT_TRIANGLE_LIST, game.getTerrain().getHandle().getTerrainFileResourceGroup()); | ||
// verts | ||
mo.position(vector3(-1, -1, -1)); | ||
mo.textureCoord(vector2(0,0)); | ||
mo.position(vector3(-1, -1, 1)); | ||
mo.textureCoord(vector2(0,1)); | ||
mo.position(vector3(1, -1, 1)); | ||
mo.textureCoord(vector2(1,1)); | ||
mo.position(vector3(1, -1, -1)); | ||
mo.textureCoord(vector2(1,0)); | ||
// tris | ||
mo.index(0); mo.index(1); mo.index(2); | ||
mo.index(0); mo.index(2); mo.index(3); | ||
|
||
mo.end(); | ||
return mo; | ||
} | ||
|
||
// `frameStep()` runs every frame; `dt` is delta time in seconds. | ||
void frameStep(float dt) | ||
{ | ||
ImGui::Text("Num manual objects: "+gManualObjects.length()); | ||
|
||
if (ImGui::Button("make plane at character position")) | ||
{ | ||
string moname = makeID("mo-"+gManualObjects.length()); | ||
string matname = "sign-autostrasse"; | ||
Ogre::ManualObject@ mo = makePlane(moname, matname); | ||
Ogre::SceneNode@ snode = gGroupingSceneNode.createChildSceneNode(moname+"-node"); | ||
snode.attachObject(cast<Ogre::MovableObject@>(mo)); | ||
snode.setPosition(game.getPersonPosition()+vector3(0,2,0)); | ||
gManualObjects.insertLast(mo); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// \title example - OGRE - MeshedConcrete | ||
// \brief shows how to make custom mesh along the ground | ||
// =================================================== | ||
|
||
|
||
array< Ogre::ManualObject@ > gManualObjects; | ||
Ogre::SceneNode@ gGroupingSceneNode = game.getSceneManager().getRootSceneNode().createChildSceneNode(makeID("")); | ||
int gNumTilesX = 2; | ||
int gNumTilesZ = 2; | ||
float gTileSizeX = 1.f; | ||
float gTileSizeZ = 1.f; | ||
float gHeightBias = 0.1; // 10cm above ground | ||
bool gDebugLog = true; | ||
|
||
string makeID(string name) | ||
{ | ||
// to avoid clash with leftover scene nodes created before, we include the NID in the name - using automatic global var `thisScript`. | ||
return "example-OGRE-ManuaObject.as(NID:"+thisScript+"): "+name; | ||
} | ||
|
||
Ogre::ManualObject@ makeGrass(string meshName, string matName) | ||
{ | ||
Ogre::ManualObject@ mo = game.getSceneManager().createManualObject(meshName); | ||
mo.begin(matName, Ogre::OT_TRIANGLE_LIST, game.getTerrain().getHandle().getTerrainFileResourceGroup()); | ||
|
||
TerrainClass@ terrn = game.getTerrain(); | ||
int numVerts = 0; | ||
vector3 startPos = game.getPersonPosition() - vector3(gTileSizeX*(gNumTilesX/2), 0, gTileSizeZ*(gNumTilesZ/2)); | ||
float tileSizeU = (1.f/gNumTilesX); // texcoords, aka UV coords | ||
float tileSizeV = (1.f/gNumTilesZ); | ||
for (int x = 0; x < gNumTilesX; x++) | ||
{ | ||
for (int z = 0; z < gNumTilesZ; z++) | ||
{ | ||
if (gDebugLog) { game.log("DBG: adding tile X="+x+"/"+gNumTilesX+" Z="+z+"/"+gNumTilesZ); } | ||
|
||
// world horizontal position | ||
float tileX = x*gTileSizeX + startPos.x; | ||
float tileZ = z*gTileSizeZ + startPos.z; | ||
// texcoords, aka UV coords | ||
float tileU = x*tileSizeU; | ||
float tileV = z*tileSizeV; | ||
|
||
if (gDebugLog){game.log("DBG \tTileX="+tileX+" tileZ="+tileZ+" tileU="+tileU+" tileV="+tileV);} | ||
|
||
// verts | ||
mo.position(vector3 (tileX, terrn.getHeightAt(tileX, tileZ)+gHeightBias, tileZ)); | ||
mo.textureCoord(vector2(tileU, tileV)); | ||
|
||
mo.position(vector3 (tileX, terrn.getHeightAt(tileX, tileZ+gTileSizeZ)+gHeightBias, tileZ+gTileSizeZ)); | ||
mo.textureCoord(vector2(tileU, tileV+tileSizeV)); | ||
|
||
mo.position(vector3 (tileX+gTileSizeX, terrn.getHeightAt(tileX+gTileSizeX, tileZ+gTileSizeZ)+gHeightBias, tileZ+gTileSizeZ)); | ||
mo.textureCoord(vector2(tileU+tileSizeU, tileV+tileSizeV)); | ||
|
||
mo.position(vector3 (tileX+gTileSizeX, terrn.getHeightAt(tileX+gTileSizeX, tileZ)+gHeightBias, tileZ)); | ||
mo.textureCoord(vector2(tileU+tileSizeU, tileV)); | ||
|
||
// tris | ||
mo.index(numVerts+0); mo.index(numVerts+1); mo.index(numVerts+2); | ||
mo.index(numVerts+0); mo.index(numVerts+2); mo.index(numVerts+3); | ||
|
||
numVerts+= 4; | ||
} | ||
} | ||
|
||
mo.end(); | ||
return mo; | ||
|
||
} | ||
|
||
// `frameStep()` runs every frame; `dt` is delta time in seconds. | ||
void frameStep(float dt) | ||
{ | ||
ImGui::TextDisabled("MESHED CONCRETE EXAMPLE"); | ||
ImGui::TextDisabled("Generates one-layer mesh along ground"); | ||
ImGui::TextDisabled("Remember, XZ are horizontal, Y is up."); | ||
|
||
ImGui::Separator(); | ||
|
||
ImGui::Text("Num manual objects: "+gManualObjects.length()); | ||
|
||
|
||
ImGui::InputInt("Num tiles X", gNumTilesX); | ||
ImGui::InputInt("Num tiles Z", gNumTilesZ); | ||
ImGui::InputFloat("Tile size X", gTileSizeX); | ||
ImGui::InputFloat("Tile size Z", gTileSizeZ); | ||
ImGui::InputFloat("Height bias (m)", gHeightBias); | ||
ImGui::Checkbox("Debug logging", gDebugLog); | ||
|
||
if (ImGui::Button("add mesh")) | ||
{ | ||
string moname = makeID("mo-"+gManualObjects.length()); | ||
string matname = "taxiwayconcrete"; | ||
Ogre::ManualObject@ mo = makeGrass(moname, matname); | ||
Ogre::SceneNode@ snode = gGroupingSceneNode.createChildSceneNode(moname+"-node"); | ||
snode.attachObject(cast<Ogre::MovableObject@>(mo)); | ||
// unlike the ManualObject example, we don't position the node - verts are already in world position. | ||
gManualObjects.insertLast(mo); | ||
} | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters