Controlling FreeCur...
 

Controlling FreeCurve through Runtime Code  

  RSS

Rory
 Rory
(@rory)
Admin
Joined: 1 year ago
Posts: 43
14/12/2017 12:02 pm  

FreeCurve is perhaps one of the more versatile shape generators. What would it take to allow players to manipulate FreeCurve at runtime?

zz AXNode FreeCurve


Quote
trialnterror
(@trialnterror)
Joined: 1 year ago
Posts: 10
14/12/2017 1:05 pm  

continued from the unity forums...

I'm currently trying to achieve this in the following way:

The following code seems to be working:

public class AXWallTest : MonoBehaviour {
AXModel m_Model;
[SerializeField]
List<Transform> transforms;

// Use this for initialization
void Start () {
m_Model = GetComponent<AXModel>();

AXParametricObject nodePO = m_Model.parametricObjects.FirstOrDefault(p => p.Name == "FreeCurve_1");
nodePO.curve.Clear();

foreach (var t in transforms) {
Vector2 v = new Vector2(t.position.x, t.position.z);
nodePO.curve.Add ( new CurvePoint(v) );
}

m_Model.autobuild();
}
}

The shape in the AX editor updates perfectly to the transforms I put in the scene. HOWEVER: I still need to click the "rebuild" button to let it have any effect... Do I need to call some kind of "update" function on the model itself? 
I've tried the build, buildall and buildmodel functions, but they seem to have no effect...

edit: so now the model rebuilds itself, but ONLY if I put the model.autobuild() call in the update function. Can't imagine that this is very efficient, so what am I missing?

 The above code seems to work. Apparently I made a mistake with an AX relation in my first attempt, which created some errors that in turn prohibited my script from working correctly.


ReplyQuote
Rory
 Rory
(@rory)
Admin
Joined: 1 year ago
Posts: 43
14/12/2017 1:08 pm  

Yes - the function is called model.autobuild();

More in a few minutes - my battery is running out!


ReplyQuote
RuinsOfFeyrin
(@ruinsoffeyrin)
Joined: 1 year ago
Posts: 11
14/12/2017 1:18 pm  

To get specific to trialnterrorgames question.

Yes, you need to call model.autobuilt() as rory mentioned.

Also putting the values of a vector directly into an InptPoint will not give you the expected results, unless you have already multipled those values by IntPointPrecision


ReplyQuote
trialnterror
(@trialnterror)
Joined: 1 year ago
Posts: 10
14/12/2017 1:26 pm  
Posted by: Rory

Yes - the function is called model.autobuild();

More in a few minutes - my battery is running out!

This works, but ONLY if I put the model.autobuild() call in the update function. (doesn't do anything when called from the Start function, and neither when I put all the above code in the Awake function and the autobuild() call in the Start function). Can't imagine that this is very efficient, so what am I missing?


ReplyQuote
trialnterror
(@trialnterror)
Joined: 1 year ago
Posts: 10
14/12/2017 1:29 pm  
Posted by: RuinsOfFeyrin

To get specific to trialnterrorgames question.

Yes, you need to call model.autobuilt() as rory mentioned.

Also putting the values of a vector directly into an InptPoint will not give you the expected results, unless you have already multipled those values by IntPointPrecision

I'm not sure I know what you mean. Is CurvePoint a subclass of InptPoint? Right now it seams to place the nodes on the correct position, but I still feel I'm just stumbling through the dark, accidentaly stumbling upon working code without any clue why or how some things work and others don't...


ReplyQuote
RuinsOfFeyrin
(@ruinsoffeyrin)
Joined: 1 year ago
Posts: 11
14/12/2017 1:33 pm  

Heya, unmoderated now.

Sorry, i didn't realize you were putting it in a CurvePoint at first. Usually you deal in Paths, which use IntPoints, but you are directly accessing the freeCurve structure it uses to build the paths, which is what threw me off. Most nodes are not able to have their paths manipulated like the freecurve is, and i forgot that.


ReplyQuote
RuinsOfFeyrin
(@ruinsoffeyrin)
Joined: 1 year ago
Posts: 11
14/12/2017 1:34 pm  

The reason autoBuild does not work in start or awake is that i do not think the model is fully loaded yet.


ReplyQuote
trialnterror
(@trialnterror)
Joined: 1 year ago
Posts: 10
14/12/2017 2:08 pm  

any variable or function I can check to see if the model is fully loaded?


ReplyQuote
RuinsOfFeyrin
(@ruinsoffeyrin)
Joined: 1 year ago
Posts: 11
14/12/2017 2:25 pm  

Seems like you are comfortable in the code, so here is something you can do.

In AXModel.cs is where the initial loading of the model Occurs, look for  Enabled and Start(i think its start) functions. These do the initial loading of a model when it is loaded into a scene, or when the scene loads. What i would recommend doing is adding a delegate for an event at the top of the AXModel class.

public delegate void ModelEventDelegate(AXModel model);

 

and then put the event on the model like

public event ModelEventDelegate OnEnabled;

public event ModelEventDelegate OnStart;

then in enable and call the events

This will allow you to hook those events from other code, including Awake events, and assign a callback for when the model has actually loaded.
I'm unsure order of events, Enabled, or Start first, or if both get called, so you will have to check that. But this will allow you to do what you want.

 

 


ReplyQuote
Rory
 Rory
(@rory)
Admin
Joined: 1 year ago
Posts: 43
14/12/2017 2:34 pm  

Take a look at the classes in the folder Archimatix/Scripts/Runtime

In  AXRuntimeControllerTemplate, the Start() function calls InitializeController(), which does the initial build of the model.

Also, the Update function has an optimization where it does not call autobuild(), but rather sets the model as altered or dirty.

    void Update () {

        // Any game specific code that sets or gets the width in the course of player events.

        // Final step in Update: Let the model know if a parameter has been reset
        if (parameterWasAltered)
        {
            parameterWasAltered = false;
            if (model != null)
                model.isAltered();
        }

    }

The difference being that autobuild() generates the meshes AND the GameObjects, which is more computationally intensive, while isAltered() tells the model to jut generate the meshes and use Graphics.DrawMesh to render them temporarily. 

When using GUI elements, on a mouseup, say on a slider, call autobuild(). When dragging the slider, call isAltered().

 


ReplyQuote
trialnterror
(@trialnterror)
Joined: 1 year ago
Posts: 10
14/12/2017 3:01 pm  

Edit: ignore this, after starting up a new project I didn't get the error anymore.

Alright, next issue 😀

I keep running into this error:

InvalidOperationException: Operation is not valid due to the current state of the object
System.Collections.Generic.Stack`1[System.Double].Pop ()
AX.SoftCircuits.Eval.ExecuteTokens (System.Collections.Generic.List`1 tokens) (at Assets/Archimatix/Scripts/Core/plugins/SoftCircuits/SCMathParser.cs:493)
AX.SoftCircuits.Eval.Execute (System.String expression) (at Assets/Archimatix/Scripts/Core/plugins/SoftCircuits/SCMathParser.cs:121)
AX.AXParametricObject.parseMath (System.String expr) (at Assets/Archimatix/Scripts/Core/AXParametricObject.cs:5774)
AX.AXParametricObject.executeCodeBloc (System.Collections.Generic.List`1 lines, AXGeometryTools.AXTurtle shape) (at Assets/Archimatix/Scripts/Core/AXParametricObject.cs:5625)
AX.Generators.Shape.generate (Boolean makeGameObjects, AX.AXParametricObject initiator_po, Boolean isReplica) (at Assets/Archimatix/Scripts/Core/Generators/ShapeGenerators.cs:62)
AX.AXParametricObject.generateOutputNow (Boolean makeGameObjects, AX.AXParametricObject initiator_po, Boolean renderToOutputParameter, Boolean forceGenerate) (at Assets/Archimatix/Scripts/Core/AXParametricObject.cs:4391)
AX.AXParametricObject.generateOutputNow (Boolean makeGameObjects, AX.AXParametricObject initiator_po) (at Assets/Archimatix/Scripts/Core/AXParametricObject.cs:4300)
AX.AXParametricObject.generateOutputNow (Boolean makeGameObjects, AX.AXParametricObject initiator_po, Boolean renderToOutputParameter, Boolean forceGenerate) (at Assets/Archimatix/Scripts/Core/AXParametricObject.cs:4349)
AX.AXModel.regenerateAXMeshes (Boolean doCacheTheThumbnails) (at Assets/Archimatix/Scripts/Core/AXModel.cs:3047)
AX.AXModel.Start () (at Assets/Archimatix/Scripts/Core/AXModel.cs:734)

With or without my script, it shows this error. The error is rooted in the Start function of the AXModel, so it breaks while executing regenerateAXMeshes(true); and thus never executing my delegate... 

I also get this error when I don't attach my script.


ReplyQuote
Rory
 Rory
(@rory)
Admin
Joined: 1 year ago
Posts: 43
14/12/2017 3:09 pm  

That error looks like it is related to a bad relation expression. Do you have a graph with any relations defined?


ReplyQuote
trialnterror
(@trialnterror)
Joined: 1 year ago
Posts: 10
14/12/2017 3:49 pm  
Posted by: Rory

That error looks like it is related to a bad relation expression. Do you have a graph with any relations defined?

I redid the graph 3 times in my original project and created a new AX model twice, but the error persisted. However, in a new project I didn't encounter the error once, so it must have something to do with my first project or scene.

The script seems to be working now. I've updated the first post with the current code, but I'll keep this thread updated whenever I encounter some issues.

Thank you for all the help, everyone!!


ReplyQuote
Share:
  
Working

Please Login or Register