Difference between revisions of "Mesh Operation - Manual implementation"
(→Sample Code) |
|||
Line 7: | Line 7: | ||
The package/item should be of the type LXsITYPE_MESHOP, and the modifier should read the inputs it requires, and output the ILxMeshOperation COM object to the LXsICHAN_MESHOP_OBJ channel. The LXsMESHOP_PMODEL server tag should not be present on the ILxMeshOperation spawned by this modifier. | The package/item should be of the type LXsITYPE_MESHOP, and the modifier should read the inputs it requires, and output the ILxMeshOperation COM object to the LXsICHAN_MESHOP_OBJ channel. The LXsMESHOP_PMODEL server tag should not be present on the ILxMeshOperation spawned by this modifier. | ||
− | + | ===Sample Code=== | |
The following sample code implements a very basic mesh operation, item type and modifier that creates a grid at the centre of the world. The size of the grid is determined by scene time. | The following sample code implements a very basic mesh operation, item type and modifier that creates a grid at the centre of the world. The size of the grid is determined by scene time. | ||
Revision as of 23:40, 27 June 2016
Contents
Mesh Operations can be integrated directly into the procedural modelling system, allowing them to be evaluated as part of the procedural stack. A modifier should spawn the ILxMeshOperation server and store it in the MeshOpObj channel on the Mesh Operation Item. This channel is then evaluated by the procedural modelling system, and it's functions are called to perform the mesh edit.
Whilst we provide a method for automatically generating a mesh operation item type and modifier, in some cases, a mesh operation has to be implemented manually, for example, if the mesh operation depends on other items in the scene or time for it's evaluation, there's no way this can be provided by the automatically generated mesh operation item. In these cases, the auto conversion cannot be used to convert the ILxMeshOperation interface into a Mesh Operation item. Instead, a Package and Modifier need to be created that can provide the mesh operation to the procedural system.
The package/item should be of the type LXsITYPE_MESHOP, and the modifier should read the inputs it requires, and output the ILxMeshOperation COM object to the LXsICHAN_MESHOP_OBJ channel. The LXsMESHOP_PMODEL server tag should not be present on the ILxMeshOperation spawned by this modifier.
Sample Code
The following sample code implements a very basic mesh operation, item type and modifier that creates a grid at the centre of the world. The size of the grid is determined by scene time.
C++
/* * The Package and PackageInstance define the item that is added to the * procedural mesh operation stack. */ class Instance : public CLxImpl_PackageInstance { public: static void initialize () { CLxGenericPolymorph *srv = NULL; srv = new CLxPolymorph <Instance>; srv->AddInterface (new CLxIfc_PackageInstance <Instance>); lx::AddSpawner ("prim.plane.inst", srv); } }; class Package : public CLxImpl_Package { public: static void initialize () { CLxGenericPolymorph *srv = NULL; srv = new CLxPolymorph <Package>; srv->AddInterface (new CLxIfc_Package <Package>); srv->AddInterface (new CLxIfc_StaticDesc <Package>); lx::AddServer ("prim.plane", srv); } Package () : _inst_spawn ("prim.plane.inst") {} LxResult pkg_TestInterface ( const LXtGUID guid) LXx_OVERRIDE { _inst_spawn.TestInterfaceRC (guid); } LxResult pkg_Attach ( void **ppvObj) LXx_OVERRIDE { _inst_spawn.Alloc (ppvObj); return ppvObj[0] ? LXe_OK : LXe_FAILED; } static LXtTagInfoDesc descInfo[]; private: CLxSpawner <Instance> _inst_spawn; }; LXtTagInfoDesc Package::descInfo[] = { { LXsPKG_SUPERTYPE, LXsITYPE_MESHOP }, { 0 } }; /* * The Mesh Operation is spawned by the modifier and generates a plane in * the procedural mesh. */ class MeshOp : public CLxImpl_MeshOperation { public: static void initialize () { CLxGenericPolymorph *srv = NULL; srv = new CLxPolymorph <MeshOp>; srv->AddInterface (new CLxIfc_MeshOperation <MeshOp>); lx::AddSpawner ("prim.plane.op", srv); } LxResult mop_Evaluate ( ILxUnknownID mesh_obj, LXtID4 type, LXtMarkMode mode) LXx_OVERRIDE { CLxUser_Mesh mesh (mesh_obj); CLxUser_Polygon polygon; CLxUser_Point point; LXtPolygonID poly_id = NULL; LXtPointID point_id[4]; LxResult result = LXe_FAILED; LXtVector pos; double size = 0.5; static double positions[4][3] = {{-0.5, 0.0, -0.5}, { 0.5, 0.0, -0.5}, { 0.5, 0.0, 0.5}, {-0.5, 0.0, 0.5}}; size = _size * 2.0; if (mesh.test ()) { polygon.fromMesh (mesh); point.fromMesh (mesh); if (polygon.test () && point.test ()) { for (unsigned i = 0; i < 4; i++) { LXx_VSCL3 (pos, positions[i], size); point.New (pos, &point_id[i]); } polygon.New (LXiPTYP_FACE, point_id, 4, 0, &poly_id); mesh.SetMeshEdits (LXf_MESHEDIT_GEOMETRY); result = LXe_OK; } } return result; } double _size; }; /* * The Modifier is associated with the all items of our type, and it reads * time as an input, spawns the mesh operation and writes it to the mesh * operation object channel. */ class ModifierElement : public CLxItemModifierElement { public: ModifierElement ( CLxUser_Evaluation &eval, ILxUnknownID item_obj) { CLxUser_Item item (item_obj); _time_index = -1; _output_index = -1; if (item.test ()) { /* * Allocate time as an input and the mesh * operation object as an output. */ _time_index = eval.AddTime (); _output_index = eval.AddChan (item, LXsICHAN_MESHOP_OBJ, LXfECHAN_WRITE); } } void Eval ( CLxUser_Evaluation &eval, CLxUser_Attributes &attr) LXx_OVERRIDE { CLxUser_ValueReference val_ref; MeshOp *meshOp = NULL; ILxUnknownID meshOp_obj = NULL; double time = 0.0; CLxSpawner <MeshOp> spawner ("prim.plane.op"); if (_output_index < 0) return; if (_time_index >= 0) time = attr.Float (_time_index); /* * Spawn the mesh operation and copy the time channel to * it for the size. */ meshOp = spawner.Alloc (meshOp_obj); if (MeshOp) meshOp->size = time; /* * Write the mesh operation into the mesh operation item * output channel. */ if (attr.ObjectRW (_output_index, val_ref)) val_ref.SetObject (meshOp_obj); /* * Release the mesh operation COM object, as we spawned * the item directly. */ lx::UnkRelease (meshOp_obj); } private: int _output_index, _time_index; }; class ModifierServer : public CLxItemModifierServer { public: static void initialize () { CLxExport_ItemModifierServer <ModifierServer> ("prim.plane.mod"); } const char * ItemType () LXx_OVERRIDE { /* * Associate the modifier with all items of our type. */ return "prim.plane"; } CLxItemModifierElement * Alloc ( CLxUser_Evaluation &eval, ILxUnknownID item_obj) LXx_OVERRIDE { return new ModifierElement (eval, item_obj); } }; void initialize () { Package::initialize (); Instance::initialize (); MeshOp::initialize (); ModifierServer::initialize (); }