GUI Dialog Mods don't require any particular object type - they're just
hints about what's going on with the GUI. Limiting them to meshes
actually breaks the Note Popup modifier, which attaches a GUI Dialog
modifier to an empty.
The helpers added in #367 are great, but they don't quite match up with
what's being done here. Maybe that's why I neglected to convert this
over to the new thing. Anywho, just use the closest newflangled match.
The `_sound_name` field does not include the channel suffix (eg `:L` and
`:R`), so this would explode when attempting to control a stereo sound
that has been split into mono channels.
This means you can't add VisRegions to your GUI pages. You also can't
make an empty object be a panic link region. Those kinds of things just
don't make sense.
* Fix CubeMap Bug
* Adds a sanity check that raises an error if a CubeMap doesn't have an image.
* Refine coding
* Adjust a few things per Hoikas' suggestion
* Update korman/exporter/material.py
Fix line of code per Hoikas' suggestion
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>
* Update korman/exporter/material.py
---------
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>
Our calculations try to fill the entire screen with the GUI objects. So,
really, what we want the GUI Camera scaling to do is allow the artist to
make the GUI smaller onscreen by pushing the camera away. This is a
*less than* 100% scaling.
We will now calculate the area-weighted normal of all polygons in the
GUI page, then flip it to create the direction that the GUI camera
should face. This will, theoretically, be more intuitive to artists in
that the GUI camera should always point at what they've modelled instead
of imposing arbitrary rules on the coordinate system of GUI objects.
This adds just enough plumbing to be able to export GUI popup notes
using the standard xDialogToggle.py. There are still a number of TODOs
and FIXMEs in the basic stuff, but the design is mostly solid. The idea
is that you'll create a GUI page for any objects that need to appear in
a GUI. The GUI does not require an explicit GUI camera, however. For
now, an automatic GUI camera will be made facing the largest object's -Z
axis.
The Python File Nodes were always picking up the group owner's
`plAGMasterMod` key instead of the group's `plMsgForwarder` key. This is
fixed by using the appropriate generic method for fetching an
animation's key.
Blender's `bpy.ops.object.duplicate()` operator changes the underlying
object that's selected to be the duplicate while the code expected for
the underlying object to remain unchanged. This uses a lower-level ID
copy mechanism that should hopefully give the intended result.
There are some things that exist in `pre_export()`, eg animations, that
don't actually generate anything that needs to be memory managed. So,
it's ok if `pre_export()` isn't actually a generator function. It does
need to return either a generator or `None`, however.
Previously, this functionality was implemented in context-dependent operators. Considering that Korman is becoming increasingly complex and is now generating entirely new objects (potentially with modifiers) as part of its export process, it was becoming cumbersome to use those operators.
It is now possible to write
```python
my_object = yield create_something()
```
to ensure that temporary objects are always managed by the exporter. Previously, the more verbose
```python
my_object = create_something()
yield my_object
```
was needed.
In an attempt to address #359, I separated 3D stereo sounds into
separate emitter scene objects and allow the engine to position them
around the listener such that the left channel is actually on the left
of the listener (and the same for the right channel). Unfortunately,
this did not fix the bug in question. However, the code that interfaces
with sounds from the outside is now much simpler, and the improved
behavior is a win, IMO, so let's keep this.
This fixes review comments left on #367 that were caused by missing
pretends-to-be-a semantics. `BMeshObject` is intended to provide
pass-through access to `bpy.types.Object`'s attributes.
When a responder node is linked to a Python file node's
ptAttribNamedResponder socket, it will now export with the same name as
the node itself. In that way, the responder can be addressed in the
attribute's value mapping in the Python script itself.
Previously, the indentation level was hardcoded everywhere. This was
tedious before in that changing the log structure would require changing
many manual indentation values. Now that objects can be trivially
generated at export time, the export code might be much more nested that
before. So, it's better to let indentation be more implicit. This,
therefore, adds a context manager to increase the indentation using
`with` blocks. Manual indentation specification remains for
compatibility with Python 2.2 where required.
This adds a page type distinction. It will primarily be geared toward
things like GUIs and avatar animations. However, for now, we can abuse
it to allow externally created pages, such as those created by PRPShop
hacking (for particles) or from 3dsMax (avatar animations, GUIs, etc.)
to coexist more easily with our Korman-generated .age files.
If a sound message was being sent to a random sound modifier, the
responder tree might crash on export. This fixes that particular problem
and adds a mitigation to the responder code itself. Remember kids that,
in Python `None and True` is `None`...
This allows Region Sensor nodes to export
`plObjectInVolumeAndFacingDetector`, which only triggers the region
sensor when an avatar is in the region, facing a certain direction
(within a tolerance amount), and (optionally) moving forward.
BREAKING CHANGE: The Facing Target node can now only link to a single
condition node.
`find_input_socket()`.
It's possible that we may want to address input sockets before the
Node's `update()` method is called. In that case, we need to initialize
the socket ourselves. This is most likely to happen if you're doing
something gnawty in a Node's `init()` method.