Question updates at the bottom....
I'm writing a custom SketchUp export plugin in Ruby. I then recreate the geometry in Three.js using the exported data.
I'm having troubles with some component/group transformations, and tracked it down to mirroring, or geometry that has "flip along" applied for some axis. Simply put, the flip along is not respected. I can not find any SU Ruby method to find out whether any given entity has this flip along applied.
I can get a transformation matrix, and convert it (see this question of mine how), however it does not work for these flipped objects. Here's an example result; the rest of the model is fine, but the boat is obviously created using flipped boat halves, and in this picture they appear all over the place:
How can I properly take these flipped geometries into account? Do they have some kind of separate matrix, or entity flag in SU Ruby?
Note 1) I have observed similar buggy behaviour in the built-in SketchUp Collada exporter (when loading them with Three.js ColladaLoader).
Note 2) Although I believe this to be a SketchUp Ruby API issue, I tagged this with Three.js just in case there is something obvious I'm missing in regards to mirroring and Matrixes..
Note 3) If the geometries are flipped / mirrored using the scale tool instead of flip along tool (effectively the same result), they work correctly.
UPDATE:
Still struggling to apply this information, but getting closer based on this information: http://sketchucation.com/forums/viewtopic.php?f=6&t=3083
UPDATE #2:
Thanks to Thomthom, I was able to detect and apply correct flipping for objects that are not rotated. For a plain unrotated/unscaled/unflipped component the matrix is:
1.0, 0.0, 0.0
0.0, 1.0, 0.0
0.0, 0.0, 1.0
For a flipped (mirrored) component the matrix can be:
-1.0, 0.0, 0.0
0.0, 1.0, 0.0
0.0, 0.0, 1.0
So I can detect that flip easily and all is fine.
But if I arbitrarily rotate the same component (unflipped) an a couple of axes, the matrix looks like this:
-0.33, -0.58, 0,74
0.87, -0.50, 0,00
0.37, 0.64, 0,67
This works correctly in my exporter/importer, I can reapply this matrix on Three.js side.
But when that already rotated component is also mirrored, the matrix looks like this:
0.33, 0.58, -0.74
0.87, -0.50, 0.00
0.37, 0.64, 0.67
I can't get this matrix work correctly in Three.js, and the component is never mirrored, resulting in the behaviour that can be seen in the picture.
So, I'm not sure what to do. I was able to get correct results by detecting the simpler case (only flipped, not rotated or scaled), then setting for example object.scale.x = object.scale.x * -1;
in Three.js for such components. But no solution for items that are both flipped and otherwise rotated or scaled :(
Use my Transformation Inspector to visualize the SketchUp matrix in a 4x4 grid: http://extensions.sketchup.com/en/content/transformation-inspector
Martin Rinehart has written a breakdown of the transformation in SketchUp: http://www.martinrinehart.com/models/tutorial/tutorial_t.html
Find flipped axis with orientation:
module TransformationHelper
def flipped_x?
dot_x, dot_y, dot_z = axes_dot_products()
dot_x < 0 && flipped?(dot_x, dot_y, dot_z)
end
def flipped_y?
dot_x, dot_y, dot_z = axes_dot_products()
dot_y < 0 && flipped?(dot_x, dot_y, dot_z)
end
def flipped_z?
dot_x, dot_y, dot_z = axes_dot_products()
dot_z < 0 && flipped?(dot_x, dot_y, dot_z)
end
private
def axes_dot_products
[
xaxis.dot(X_AXIS),
yaxis.dot(Y_AXIS),
zaxis.dot(Z_AXIS)
]
end
def flipped?(dot_x, dot_y, dot_z)
dot_x * dot_y * dot_z < 0
end
end
module Example
def self.inspect_flipped
tr = Sketchup.active_model.selection[0].transformation
tr.extend(TransformationHelper)
puts "X Flipped: #{tr.flipped_x?.inspect}"
puts "Y Flipped: #{tr.flipped_y?.inspect}"
puts "Z Flipped: #{tr.flipped_z?.inspect}"
end
end