Panel element coordinates off by 2x?

So I created a little panel generator (for the Native integration) based on the number of knobs, leds, and jack inputs and outputs. It takes a number of assets and spreads them around so they fit the maximum height and adjust the panel width accordingly.

Right now I’m testing with the NativeExample assets. I’m using Python, with Pillow library, and I can easily export a full composite png using the exact same assets and coordinates:

panel

However when I create my elements.cpp with these same coordinates the final render was way off:

I first tried explicitly setting .coords = MetaModule::Coords::TopLeft; on all of the objects, but this didn’t change anything (and wouldn’t explain the huge jump on the Y axis).

Then I tried dividing the coordinates in half and that actually resulted in a correct (or at least much better) placement:

Am I missing some caveats to how asset placement/coordinates work?

Here is my full elements.cpp :

#include "CoreModules/CoreProcessor.hh"
#include "CoreModules/elements/element_counter.hh"
#include "CoreModules/elements/elements.hh"
#include "CoreModules/elements/element_info.hh"
#include "CoreModules/register_module.hh"
#include "HeavyMetaModule_metatest.hpp"


void init_metatest() {
  static std::array<MetaModule::Element, 8> elements;
  static std::array<ElementCount::Indices, 8> indices;


  MetaModule::Knob freq;
  freq.x_mm = 10;
  freq.y_mm = 25;
  freq.coords = MetaModule::Coords::TopLeft;
  freq.image = "metatest/components/knob.png";
  freq.short_name = "freq";
  elements[0] = freq;
  indices[0] = {.param_idx = FreqID};
  
  MetaModule::Knob vol;
  vol.x_mm = 10;
  vol.y_mm = 58;
  vol.coords = MetaModule::Coords::TopLeft;
  vol.image = "metatest/components/knob.png";
  vol.short_name = "vol";
  elements[1] = vol;
  indices[1] = {.param_idx = VolID};
  
  MetaModule::JackInput injack0;
  injack0.x_mm = 13;
  injack0.y_mm = 100;
  injack0.coords = MetaModule::Coords::TopLeft;
  injack0.image = "metatest/components/jack.png";
  injack0.short_name = "Input 0";
  elements[2] = injack0;
  indices[2] = {.input_idx = InputID0};
  
  MetaModule::JackInput injack1;
  injack1.x_mm = 13;
  injack1.y_mm = 124;
  injack1.coords = MetaModule::Coords::TopLeft;
  injack1.image = "metatest/components/jack.png";
  injack1.short_name = "Input 1";
  elements[3] = injack1;
  indices[3] = {.input_idx = InputID1};
  
  MetaModule::JackOutput outjack0;
  outjack0.x_mm = 13;
  outjack0.y_mm = 148;
  outjack0.coords = MetaModule::Coords::TopLeft;
  outjack0.image = "metatest/components/jack.png";
  outjack0.short_name = "Output 0";
  elements[4] = outjack0;
  indices[4] = {.output_idx = OutputID0};
  
  MetaModule::JackOutput outjack1;
  outjack1.x_mm = 13;
  outjack1.y_mm = 174;
  outjack1.coords = MetaModule::Coords::TopLeft;
  outjack1.image = "metatest/components/jack.png";
  outjack1.short_name = "Output 1";
  elements[5] = outjack1;
  indices[5] = {.output_idx = OutputID1};
  
  MetaModule::JackOutput outjack2;
  outjack2.x_mm = 13;
  outjack2.y_mm = 200;
  outjack2.coords = MetaModule::Coords::TopLeft;
  outjack2.image = "metatest/components/jack.png";
  outjack2.short_name = "Output 2";
  elements[6] = outjack2;
  indices[6] = {.output_idx = OutputID2};
  
  MetaModule::MonoLight ledvolled;
  ledvolled.x_mm = 18;
  ledvolled.y_mm = 87;
  ledvolled.coords = MetaModule::Coords::TopLeft;
  ledvolled.image = "metatest/components/led.png";
  ledvolled.short_name = "LED volled";
  elements[7] = ledvolled;
  indices[7] = {.light_idx = VolledID};
  

  MetaModule::ModuleInfoView info{
      .description = "Test plugin",
      .width_hp = 6,
      .elements = elements,
      .indices = indices,
  };

  MetaModule::register_module<metatestMM>("metatest", "metatest", info, "metatest/panel.png");
}

Dividing all of the x_mm/y_mm by 2 gave the correct placement.

The (virtual) Eurorack faceplate height is 128.5mm, and MetaModule faceplate PNG height is 240px, so everything is based off of that relationship. When specifying in mm, the top is 0mm and the bottom of the faceplate is 128.5mm. Looking at the y_mm coordinates in the elements.cpp array, I see some jacks with a y coordinate greater than 128.5mm, so somehow those coordinates are using the wrong units or scaling somewhere in the script that generates elements.cpp. I don’t know if you’re involving SVG files with the script, but SVGs are notoriously unit-unfriendly so it’s easy to get off track if you try to extract measurements from the SVG.

Ooooh, so we have to translate the pixel coordinates to milimeter coordinates?

It would be good to mention this clearly in the docs (I didn’t see this anywhere).

I’m currently using only PNG (the same ones from metamodule-plugin-examples/NativeExample/assets/components at main · 4ms/metamodule-plugin-examples · GitHub - pending knowledge on the licensing on these).

Will give translating with this 240/128.5 ratio a try in a bit!

When you have a panel and assets in raster/pixels it makes sense to think about everything else in pixels as well. And since the docs only said “240px height” I deducted everything else from that.

Yes, the x_mm and y_mm coordinates are in mm. I tried to put the unit into the variable name itself so it was less confusing, but I can mention it explicitly in the docs too.

It’s even more confusing than this because VCV uses a px coordinate that’s based on 75 DPI, so the panel height is 128.5mm = 5.059" = 379.425px. So there’s VCV px (379.425/panel height) and there’s MM px (240px/panel height) and there’s mm (128.5/panel height). I find it easiest to think in terms of mm because of this.

1 Like

I thought that mm stood for metamodule :rofl:

By using this ratio to convert px positions to mm it works great!

Will share the progress soon.

1 Like

Ha! I never thought of that… oh boy, I’ll document it.

1 Like