Add a custom shape to a Maya scene from C++ - c++

I'm in the process of creating a custom import plugin for maya. I already wrote some import code and created a custom MPxSurfaceShape class (I'm mainly interested in drawing the surface from within the viewport).
The shape gets crated by a MPxCommand which reads a file from the disk. Now I would like to add this object to my maya scene from within the plugin. But unfortunately I can't find a function that takes a MPxNode/MPxSurfaceShape and adds it to Maya so that it can be displayed.
In all examples I've seen the node is instantiated from within mel. But I want to link this instance a file. Which prevents me from just creating the node and then editing it.
A similar solution might be found in either the apiMeshShape example in the maya plugin folder or here: https://github.com/ADN-DevTech/Maya-Locator/ (also supports the loading of external data).

Here's something I hope will help.
MDagModifier dagMod;
MObject newNode = dagMod.MDGModifier::createNode("Node Name")
dagMod.doIt()
or
MDagModifier dagMod;
MObject newNode = dagMod.MDGModifier::createNode(Node::id)
dagMod.doIt()
From there you have an MObject you can make into other things.
//Dag Node example.
MFnDagNode new_MDagNode(newNode);
//Dependency Node.
MFnDependencyNode new_DependNode(newNode);
The MPxNode also has thisMObject() which will give you the current MObject in the MPxNode.
http://download.autodesk.com/us/maya/2010help/API/class_m_px_node.html#9608c582da0945e792c3f9893661404d
Again I'm not sure I fully understand the question, but I hope this helps.

Related

Visualization of dynamically created modules

I am building a dynamic multi agent simulation in OMNeT and for this I have to create new modules at runtime. The module creation is working, however, the modules created at runtime are not appearing in the 3D visualization.
module "node" is created sucessfully
Does anyone know how to make the module appear in the visualization? Do I have to update the visualization module?
omnet.ini:
[General]
network = AgentNetwork
*.visualizer.osgVisualizer.typename = "IntegratedOsgVisualizer"
*.visualizer.*.mobilityVisualizer.animationSpeed = 1
*.visualizer.osgVisualizer.sceneVisualizer.typename = "SceneOsgEarthVisualizer"
*.visualizer.osgVisualizer.sceneVisualizer.mapFile = "hamburg.earth"
AgentSpawner:
void AgentSpawner::initialize()
{
cMessage *timer = new cMessage("timer");
scheduleAt(1.0, timer);
}
void AgentSpawner::handleMessage(cMessage *msg)
{
cModuleType *moduleType = cModuleType::get("simulations.Agent");
cModule *module = moduleType->create("node", getParentModule());
// set up parameters and gate sizes before we set up its submodules
module->par("osgModel") = "3d/glider.osgb.(20).scale.0,0,180.rot";
module->getDisplayString().parse("p=200,100;i=misc/aircraft");
module->finalizeParameters();
// create internals, and schedule it
module->buildInside();
module->callInitialize();
module->scheduleStart(simTime()+5.0);
}
The OSG visualization info is maintained totally separately from the actual simulation model module object (that's because the visualization must be ALWAYS optional in the simulation, so make sure your simulation builds fine with OSG totally turned off). This means that an entirely different data structure is built during initialization time from the existing network nodes. As this is done only once during the initialization, dynamically created modules will not have their visualization counterpart data structure.
The code which created the corresponding objects is here.
The solution would be to look up the NetworkNodeOsgVisualizer module in your AgentSpawner code then create and add the corresponding data structures (NetworkNodeOsgVisualization objects). The needed methods (create and add) are there, but sadly they are protected, so you many need to modify the INET code and make them public to be able to call them.

Is it possible to inject a component that doesn't have a prefab/GameObject associated with it?

I have a game object (a cube, let's say) which exists in the scene, and I want it to have an injectable component. I want to be able to say, for example: My cube has an IShotFirer member, which can resolve to either a BoomShotFirer or a BangShotFirer MonoBehavior component, both of which implement IShotFirer. When binding happens, I want this component to be added to the cube object.
public class CubeBehavior : MonoBehaviour
{
[Inject]
private IShotFirer shotFirer;
}
Is it possible to do this without 1) needing an existing prefab which contains one of these Bang/Boom components, or 2) needing an existing scene object which has one of these components attached?
In other words, I want to be able to dynamically add the component to my game object depending on the bindings, and not relying on anything other than the script files which define either BoomShotFirer or BangShotFirer. But the docs seem to imply that I need to find an existing game object or prefab (e.g. using .FromComponentsInChildren(), etc.)
Is it possible to do this without 1) needing an existing prefab which
contains one of these Bang/Boom components, or 2) needing an existing
scene object which has one of these components attached?
Yes, it is.
Zenject provides a host of helpers that create a new components and bind them -- quoting the docs:
FromNewComponentOnRoot - Instantiate the given component on the root of the current context. This is most often used with GameObjectContext.
Container.BindInterfacesTo<BoomShotFirer>().FromNewComponentOnRoot();
FromNewComponentOn - Instantiate a new component of the given type on the given game object
Container.BindInterfacesTo<BoomShotFirer>().FromNewComponentOn(someGameObject);
FromNewComponentOnNewGameObject - Create a new game object at the root of the scene and add the Foo MonoBehaviour to it
Container.BindInterfacesTo<BoomShotFirer>().FromNewComponentOnNewGameObject();
For bindings like this one that create new game objects, there are also extra bind methods you can chain:
WithGameObjectName = The name to give the new Game Object associated with this binding.
UnderTransformGroup(string) = The name of the transform group to place the new game object under.
UnderTransform(Transform) = The actual transform to place the new game object under.
UnderTransform(Method) = A method to provide the transform to use.
That list is not even exhaustive, be sure to check the readme and the cheatsheet (from both of which I have extracted the info above).
Also understand that, as usual, you can append .AsSingle(), .AsTransient() and .AsCached() to achieve the desired result.

Node creation or apperance at run time in Omnet (INET)

I need to create a node at run time, with similar parameters as the other nodes. For that I am creating a dynamic node in ned file as:-
host_send4: meshnode {
parameters:
#dynamic;
#display("p=1000,535;r=200,green;i=device/smallrouter");
}
To implement this node in C++ file, I add this code:-
cModuleType *meshnode1 = cModuleType::get("inet.networklayer.manetrouting.PASER.meshnode");
cModule *mod = meshnode1->createScheduleInit("host_send4", this);
cDisplayString& dispstr = mod->getDisplayString();
dispstr.parse("p=1000,535;r=200,green;i=device/smallrouter");
mod->buildInside();
mod->scheduleStart(simTime()+5*beaconInterval);
But I am not able to build it properly. I think I am in need of any example on this. Can anybody help me to point out an example in INETMANET of mixim or any other oment framework, where this functionality is already implemented.
Thanks for your help.
I have also though of creating a node statically, which would appear in simulation at later point of time. Is it possible and is there any example with runtime appearance and disappearance of node in INET or other OMNET framework.
The OMNeT++ User Manual has a section dedicated to this. According to this you don't need buildInside() and scheduleStart() when using createScheduleInit().
An example how this is performed can be seen in the Veins framework - more precisely in the TraCIScenarioManager. The important lines for you are probably:
cModule* parentmod = getParentModule();
if (!parentmod) error("Parent Module not found");
cModuleType* nodeType = cModuleType::get(type.c_str());
if (!nodeType) error("Module Type \"%s\" not found", type.c_str());
cModule* mod = nodeType->create(name.c_str(), parentmod, nodeVectorIndex, nodeVectorIndex);
mod->finalizeParameters();
mod->getDisplayString().parse(displayString.c_str());
mod->buildInside();
mod->scheduleStart(simTime() + updateInterval);

Adding to a list from another class

I am trying to add the instance of an object that I click on to a list on my control object. However when I do so it says that the reference is not set to an instance of an object. The code I have to instantiate the list on the control object is:
public List<Transform> selected = new List<Transform>();
And I tried to add to it to that list using this code attached to the unit:
if (!selected)
{
// Set selected state
selected = true;
// Add to Selected List
control.GetComponent<ForwardCommandScript>().selected.Add(this.transform);
// Set material colour brighter
oldColour = gameObject.renderer.material.color;
newColour = oldColour + new Color(0.2f, 0.2f, 0.2f);
gameObject.renderer.material.color = newColour;
}
I have tried with transform as well. Later I will try to remove it by finding a reference id that was set when the unit is instantiated so should I try to add the script instead of the object if I need to find its variables and then delete the game object attached to the script. I have tried with the GameObject, transform and the class. I wanted to use the class so I can easily access the variables. I have posted this on unity answers and forums but no one replied in the week it was up and I don't like reposting the same stuff on the same site.
Cheers, Scobbo
Your error NullReferenceException: Object reference not set to an instance of an object states that something in the associated line is null. Since the error message doesn't state which part is null, you have to split your code up and check which part is failing.
I'm not sure how you split it up, but try it this way:
var script = control.GetComponent<ForwardCommandScript>();
if (script == null) Debug.Log("script not found");
if (script.selected == null) Debug.Log("selected is null");
script.selected.Add(this.transform);
Now you should get one of the two messages in your debug log before the exception raises. Either the script was not found and you have to check if it is correctly assigned to the game object and if control is the correct game object, or selected is null which should not happen if you initialized it like you posted...
Thanks for adding the complete Error Message :)
you need to replace
control.GetComponent<ForwardCommandScript>().selected.Add(this.transform);
with
control.GetComponent<ForwardCommandScript>().selected.Add(transform);
because
this
is a reference to the script and not the GameObject. you could also use gameObject.transform which transform is just an abbreviation for

Using particles in cocos2d android

I'm working on a game for android using Cocos2D-android and when I'm trying to use the CCQuadParticleSystem class, the CTOR just returns null. I spent hours searching for an example or a tutorial on this and all I found was other people asking about the same exact thing. It just returns null. I have my .plist file in my assets folder - the same file which is working just great with Cocos2D-X and IOS. According to the good people at github.com it should work so I must be doing something wrong but like I said... it just returns null when I call the CTOR with or without casting:
CCQuadParticleSystem p1 = (CCQuadParticleSystem) CCQuadParticleSystem.particleWithFile("fire.plist");
CCParticleSystem p2 = CCQuadParticleSystem.particleWithFile("fire.plist");
Please, anyone ???
if It's of use, this is the .plist file I'm working with
Have a look on this example :
link for plist
you'll get the way how to handle plist file .