|
struct Test_MeshFromStrandsModifier
|
|
(
|
|
-- Tests that a distribution map can be assigned to control which proxy mesh is used for which strand in Mesh From Strands modifier
|
|
function Test_ProxyDistributionMap =
|
|
(
|
|
-- Create a plane with 3x3 segments (so that there are are no vertices going exactly down the middle)
|
|
distributionObject = Plane lengthsegs:3 widthsegs:3
|
|
|
|
-- Create a simple box and another plane, we'll use these as proxy meshes
|
|
boxProxy = Box lengthsegs:1 widthsegs:1 heightsegs:1
|
|
planeProxy = Plane lengthsegs:1 widthsegs:1
|
|
|
|
max modify mode
|
|
|
|
-- Add guides from surface modifier and make sure we'll use vertices to generate strands, so that we always have a predictable strand count
|
|
select distributionObject
|
|
modPanel.addModToSelection (Ox_Guides_from_Surface())
|
|
distributionObject.modifiers[#Ox_Guides_from_Surface].method = 4
|
|
|
|
-- Add "Ox Mesh From Strands" modifier
|
|
modPanel.addModToSelection (Ox_Mesh_from_Strands())
|
|
$.modifiers[#Ox_Mesh_from_Strands].type = 2
|
|
|
|
-- Add the two proxy objects
|
|
$.modifiers[#Ox_Mesh_from_Strands].addproxyobject boxProxy
|
|
$.modifiers[#Ox_Mesh_from_Strands].addproxyobject planeProxy
|
|
|
|
-- Assign a new checkers texture to the proxy map slot
|
|
$.modifiers[#Ox_Mesh_From_Strands].proxyDistributionMap = Checker ()
|
|
|
|
-- TODO: Add some assertions
|
|
|
|
-- Cleanup
|
|
delete distributionObject
|
|
delete boxProxy
|
|
delete planeProxy
|
|
),
|
|
|
|
-- When Edit Normals modifier is applied to a proxy object and normals are edited, the custom normals should also appear in the resulting hair mesh
|
|
function Test_ProxyCustomNormalsAreCopied =
|
|
(
|
|
distributionObject = Plane()
|
|
distributionObject.width = 50
|
|
distributionObject.length = 50
|
|
|
|
proxyPlane = Plane lengthsegs:1 widthsegs:1
|
|
proxyPlane.width = 50
|
|
proxyPlane.length = 50
|
|
|
|
max modify mode
|
|
|
|
-- Edit the proxy plane normals to all point up
|
|
select proxyPlane
|
|
modPanel.addModToSelection (Edit_Normals())
|
|
editNormalsModifier = $.modifiers[1]
|
|
editNormalsModifier.Select #{1..4}
|
|
editNormalsModifier.Move [100, 100, 0]
|
|
|
|
-- Set up the mesh from strands modifier
|
|
-- Add guides from surface modifier and make sure we'll use vertices to generate strands, so that we always have a predictable strand count
|
|
select distributionObject
|
|
guidesFromSurfaceModifier = Ox_Guides_from_Surface()
|
|
TestUtilities.SetGuidesFromMeshDefaults guidesFromSurfaceModifier
|
|
guidesFromSurfaceModifier.count = 1
|
|
modPanel.addModToSelection guidesFromSurfaceModifier
|
|
|
|
-- Add "Ox Mesh From Strands" modifier
|
|
meshFromStrandsModifierInstance = Ox_Mesh_from_Strands()
|
|
meshFromStrandsModifierInstance.type = 2
|
|
meshFromStrandsModifierInstance.addproxyobject proxyPlane
|
|
meshFromStrandsModifierInstance.uniScale = off
|
|
modPanel.addModToSelection meshFromStrandsModifierInstance
|
|
|
|
-- Make sure the normals in the resulting mesh are the same as the normals in the proxy mesh
|
|
modPanel.addModToSelection (Edit_Normals())
|
|
resultEditNormalsModifier = $.modifiers[#Edit_Normals]
|
|
firstNormal = resultEditNormalsModifier.getnormal 1
|
|
|
|
-- The resulting vector should not point directly up, down, etc.
|
|
EAssert.AreNotNearEqual 0.0 firstNormal.x
|
|
EAssert.AreNotNearEqual 1.0 firstNormal.x
|
|
EAssert.AreNotNearEqual 0.0 firstNormal.y
|
|
EAssert.AreNotNearEqual 1.0 firstNormal.y
|
|
EAssert.AreNotNearEqual 0.0 firstNormal.z
|
|
EAssert.AreNotNearEqual 1.0 firstNormal.z
|
|
|
|
-- Cleanup
|
|
delete distributionObject
|
|
delete proxyPlane
|
|
),
|
|
|
|
function Test_TwistChannel =
|
|
(
|
|
distributionObject = Plane lengthsegs:1 widthsegs:1
|
|
|
|
max modify mode
|
|
|
|
-- Set up the mesh from strands modifier, use per vertex distribution
|
|
select distributionObject
|
|
|
|
-- Guides from surface modifier with vertex distribution and 2 points per strand
|
|
guidesFromSurfaceModifier = Ox_Guides_from_Surface()
|
|
modPanel.addModToSelection guidesFromSurfaceModifier
|
|
guidesFromSurfaceModifier.method = 4
|
|
guidesFromSurfaceModifier.NumSegs = 2
|
|
|
|
editGuidesModifier = Ox_Edit_Guides()
|
|
modPanel.addModToSelection editGuidesModifier
|
|
|
|
-- Create a twist channel
|
|
twistChannelIndex = editGuidesModifier.CreateChannel true "TwistChannel"
|
|
editGuidesModifier.SelectRoots #{1..4}
|
|
|
|
-- Add mesh from strands modifier with bollboard setting and apply the twist channel to twist
|
|
meshFromStrandsModifier = Ox_Mesh_from_Strands()
|
|
modPanel.addModToSelection meshFromStrandsModifier
|
|
meshFromStrandsModifier.type = 1
|
|
meshFromStrandsModifier.twistChan = ( TestUtilities.GetRootChannelIdentifier twistChannelIndex )
|
|
meshFromStrandsModifier.twistDir = 1
|
|
|
|
-- Copy resulting mesh vertices before the twist
|
|
verticesBeforeTwist = TestUtilities.GetVertexArray distributionObject.mesh
|
|
|
|
modPanel.setCurrentObject editGuidesModifier
|
|
subobjectLevel = 1
|
|
editGuidesModifier.SetChannelValueToSelection true twistChannelIndex 0.2
|
|
|
|
modPanel.setCurrentObject meshFromStrandsModifier
|
|
verticesAfterTwist = TestUtilities.GetVertexArray distributionObject.mesh
|
|
|
|
-- Make sure that, after we applied the twist channel value, the vertex positions have changed
|
|
for i = 1 to verticesBeforeTwist.count do
|
|
(
|
|
EAssert.AreNotNearEqual verticesBeforeTwist[i].x verticesAfterTwist[i].x
|
|
EAssert.AreNotNearEqual verticesBeforeTwist[i].y verticesAfterTwist[i].y
|
|
-- The Z coordinate will remain the same since twist is only along one axis
|
|
)
|
|
|
|
-- Cleanup
|
|
delete distributionObject
|
|
),
|
|
|
|
function Test_RenderSettingsWidthControlsProxyUniformWidth =
|
|
(
|
|
distributionObject = Plane lengthsegs:1 widthsegs:1
|
|
|
|
max modify mode
|
|
|
|
-- Set up the mesh from strands modifier, use per vertex distribution
|
|
select distributionObject
|
|
|
|
-- Guides from surface modifier with vertex distribution and 2 points per strand, no randomness in length, and strand length of 1
|
|
guidesFromSurfaceModifier = Ox_Guides_from_Surface()
|
|
modPanel.addModToSelection guidesFromSurfaceModifier
|
|
guidesFromSurfaceModifier.method = 4
|
|
guidesFromSurfaceModifier.NumSegs = 2
|
|
guidesFromSurfaceModifier.randomness = 0
|
|
guidesFromSurfaceModifier.guideLength = 1
|
|
|
|
-- Render settings modifier with global radius of 2
|
|
renderSettingsModifier = Ox_Render_Settings()
|
|
modPanel.addModToSelection renderSettingsModifier
|
|
renderSettingsModifier.radius = 2
|
|
|
|
-- Mesh from strands modifier with a box proxyobject and uniform scale on
|
|
meshFromStrandsModifier = Ox_Mesh_from_Strands()
|
|
modPanel.addModToSelection meshFromStrandsModifier
|
|
meshFromStrandsModifier.type = 2
|
|
meshFromStrandsModifier.uniScale = on
|
|
|
|
boxProxy = Box lengthsegs:1 widthsegs:1 heightsegs:1
|
|
meshFromStrandsModifier.addproxyobject boxProxy
|
|
|
|
-- Measure the resulting proxy mesh box by comparing the first and fifth vertex Z coordinate, it should have the size of 2
|
|
EAssert.AreNearEqual 2 ( distance( distributionObject.mesh.vertices[1].position ) ( distributionObject.mesh.vertices[2].position ) )
|
|
|
|
-- Change the render settings width to 0.5 and make sure the resulting box sizes change
|
|
renderSettingsModifier.radius = 0.5
|
|
EAssert.AreNearEqual 0.5 ( distance( distributionObject.mesh.vertices[1].position ) ( distributionObject.mesh.vertices[2].position ) )
|
|
|
|
-- Cleanup
|
|
delete distributionObject
|
|
delete boxProxy
|
|
)
|
|
)
|
|
|
|
EUnit.AddTestClass Test_MeshFromStrandsModifier
|
|
ok
|