ValueTexture: Server basics

From The Foundry MODO SDK wiki
Jump to: navigation, search

A ValueTexture is a plug-in server that implements a texture that can compute a color or percentage value.


Texture layers are item types with texture-related interfaces, but those are very complex and hard to use. So to make things easier we created the Value Texture server. Every value texture server becomes an item type, so it has some package-like features. It also runs as a modifier so it has some eval modifier-like features. Basically it serves as a lightweight way to create a texture layer that can be used for color or scalar effects.



(none special)

Sample Methods

The plug-in server class derives from CLxImpl_ValueTexture, and exports the ILxValueTexture interface. For speed purposes the class will also want to keep the packet service ready to hand.

        CLxUser_PacketService   pkt_service;

Like a package, a value texture server must define its channels. The SetupChannels() method is identical to the one used by packages.

vtx_SetupChannels (
        ILxUnknownID		 addChan)
        CLxUser_AddChannel	 ac (addChan);

        ac.NewChannel ("myInput", "percent");
        ac.SetDefault (1.0, 1);
        return LXe_OK;

The value texture reads its channel values in a modifier context. That means that it has to declare the channels it wants to read using the Evaluation Interface. This is also a good place to cache the offsets for any vector packets that it wants to read.

vtx_LinkChannels (
        ILxUnknownID		 eval,
        ILxUnknownID		 item)
        CLxUser_Evaluation	 ev (eval);

        idx_value = ev.AddChan (item, "myInput");
        tin_offset = pkt_service.GetOffset (LXsCATEGORY_SAMPLE, LXsP_TEXTURE_INPUT);
        return LXe_OK;

Linking channels occurs once as items are added or their relationships are changed. Reading channels then happens any time channel values change. For example changing time may cause channels to be read again if they are animated. Values are read from an Attributes Interface using the index cached when linking channels. The values are then stored in an allocated data structure which is returned from the method.

vtx_ReadChannels (
        ILxUnknownID		 attr,
        void		       **ppvData)
        CLxUser_Attributes	 at (attr);
        RendData		*rd = new RendData;

        rd->value  = at.Float (idx_value);
        ppvData[0] = rd;
        return LXe_OK;

Evaluation actually performs the texture computation. This may happen thousands or even millions of times per frame, so it's intended to be as fast as possible. The private data struct containing channel values is passed as data. The plug-in can read common input packets from the vector given their offset, and the results are written to the texture output packet, already extracted from the vector as an argument. Values may be written as scalar or vector.

Note also that this is a void function. Anything that can fail, such as allocations, should already have been done as part of reading channels. The texture evaluation is assumed to succeed and there is no allowance for failure.

vtx_Evaluate (
        ILxUnknownID		 vector,
        LXpTextureOutput	*tOut,
        void			*data)
        RendData		*rd = (RendData *) data;
        LXpTextureInput		*tInp;
        LXtFVector		 rgb;

        tInp = (LXpTextureInput *) pkt_service.FastPacket (vector, tin_offset);
        compute_rgb_from_pos (rd->value, tInp, rgb);

        tOut->direct   = 1;
        tOut->alpha[0] = 1.0;
        tOut->value[0] = LXx_VLEN (rgb);
        if (tInp->context == LXi_TFX_COLOR)
                LXx_VCPY (tOut->color[0], rgb);

The allocated private struct is freed by the Cleanup() method.

vtx_Cleanup (
        void			*data)
        RendData		*rd = (RendData *) data;

        delete rd;


The value texture server can also present a ChannelUI Interface for configuring the UI of its channels.

The ValueTexture::Customize() method can be passed a ValueTextureCustom Interface to allow for further customization of the texture's evaluation.