mcjCollider plugin
DS4 PC/MAC
Note: if you downloaded the mcjCollider plugin before Fenruary 15th 2019 you probably experienced problems
when dealing with Genesis 3 or Genesis 8 figures. get the new version that fix those problems ! Life is good.
History
02/19/2019 02:38AM - VERSION 3 - Correctly reports facet ids when the collider's target object is a bone
this is needed for scripts like mcjPushPullFacet
02/15/2019 Genesis 3 or Genesis 8 figures had facet groups that didn't match bone names and made the script fail, now the plugin looks for alternate names, for example, the pelvis bone can in some cases have its facet group named hip or even Hip
02/09/2019 added the Mac 64 bit version ! mcjCollider.dylib
(103k)
Introduction
mcjCollider is a plugin for Daz Studio 4.5
You point a ray at objects in a daz scene and this plugin computes the collision point and the bounce angle.
Although this plugin can be used "by hand" to achieve interesting effects, it is intended to be used by scripts and other plugins.
In the image below, a Daz Script used mcjCollider's services 256 times.
Installation
The plugin, mcjCollider.dll can be found in the attachments at the bottom of this page
This file should be placed in your daz studio plugins folder
typically it's
C:\Program Files\DAZ 3D\DAZStudio4\plugins
You can also download this manual as a pdf file.
The MAC Version ( 2019 !!! ) is a 64-bit version
the file is found at the bottom of this page :
mcjCollider.dylib
(103k)
remember to use the down-arrow to download anything on this site
it must be placed in your Daz Studio 4.10+ folder named plugins
On my MacBook it means Applications/ DAZ 3D/DazStudio4 64-bit/plugins
Usage
mcjCollider can be used on any solid object in the scene but not on objects that were converted to subD
select the objects that will be the target of the collider
It's preferable to do this selection in the Scene Tab, otherwise you may accidentally select the whole figure when the area of interest is just the torso. Parsing the whole figure is much slower since for example a character's head can comprise 30000 polygon's for a 70000 polygons figure.
example: we select the cylinder and the floor-cube ( use the CTRL key for multiple selections )
once properly installed you will find mcjCollider in the "Create" menu
now that the mcjCollider is created in the scene, it will remember the list of selected objects, so you
can deselect them if you want.
unfortunately, this list of target nodes is not saved along your scene file, so you will need to create a new mcjCollider nest time you re-use the scene
in the Scene tab, select the mcjCollider
position it so that it points toward the objects
go in the parameters tab and modify the "Ray length" property ( click only once! )
tweaking this property activates the collider
within a fraction of a second or a few seconds
the collider should jump to the collision point with the solids
the collider will also be oriented as if it had bounced on the surface
you can also use the script named "mcjActivateCollider.dsa" which is part of mcjColliderScripts.zip
if an mcjCollider is selected when you run this script, this mcjCollider will be activated, if no collider is selected, the first mcjCollider found in the scene will be activated.
mcjActivateCollider.dsa
var collider = Scene.getPrimarySelection();
if( collider )
{
if( collider.inherits( "mcjCollider" ) )
{
collider.activated();
}
else
{
collider = Scene.findNode( "mcjCollider" );
if( collider )
{
collider.activated();
}
}
}
else
{
collider = Scene.findNode( "mcjCollider" );
if( collider )
{
collider.activated();
}
}
SDK info for script/plugin developers
The short-form collision report
A parameter/channel named "report" was added to the mcjCollider node
if there was no collision, the label of the report channel contains the string value "noHit"
if there was a collision, the label of the report channel contains 5 tab-delimited values
example:
shi6f_8206 root 1 580 0
the five parameters contained in this report string are
- figure name : example: "shi6f_8206", if the collided object is not a figure, then figure name will be "none",
- node name: if the collided object is a figure, this field will be set to "root" meaning the figure's root node owns the mesh. If mcjCollider is the version for Daz Studio 3, this field would hold the name of the bone, since it owns the mesh. If the collided object is not a figure this field holds the object's name. example: "plane 3".
- facet type: 0 = triangle, 1 = square, 2 = polygon (DS3 only) )
- facet index: example: 580
- triangle index: if the facet is a square, this can be 0 or 1
example:
none plane 1 0 1
here is a script to read and unpack this report string
code: mcjCollider_example_1.dsa
collider = Scene.findNode( "mcjCollider" )
str = collider.findProperty("report").getLabel();
fields = str.split( "\t" );
bGotHit = ( fields.length > 1 )
if( bGotHit )
{
var pos = collider.getWSPos();
debug( "collision point: " + showV( pos ) );
var skelname = fields[0];
debug( "skelname " + skelname );
var nodename = fields[1];
debug( "nodename " + nodename );
var facetype = Number( fields[2] );
debug( "facetype " + facetype );
var faceno = Number( fields[3] );
debug( "faceno " + faceno );
var triangleNo = Number( fields[4] );
debug( "triangleNo " + triangleNo );
}
function showV( v )
{
return( "[ ", v.x + ", " + v.y + ", " + v.z + "]" );
}
The long-form collision report
As well as activating ( firing) the mcjCollider, the function/slot "activated()" returns a long-form collision report
it contains the 5 short-form-report items plus the UV texture coordinates of the hit point and the indexes of the
vertices, the normals and the UVs of the collided facet.
here's an example showing how to obtain and unpack values from this report string
code: mcjCollider_example_2.dsa
collider = Scene.findNode( "mcjCollider" )
str = collider.activated();
fields = str.split( "\t" );
bGotHit = ( fields.length > 1 )
if( bGotHit )
{
var pos = collider.getWSPos();
debug( "collision point: " + showV( pos ) );
var skelname = fields[0];
debug( "skelname " + skelname );
var nodename = fields[1];
debug( "nodename " + nodename );
var facetype = Number( fields[2] );
debug( "facetype " + facetype );
var faceno = Number( fields[3] );
debug( "faceno " + faceno );
var triangleNo = Number( fields[4] );
debug( "triangleNo " + triangleNo );
var hitUV = new DzVec3( Number(fields[5]), Number(fields[6]), 0 );
debug( "hitUV = ( " + hitUV.x + ", " + hitUV.y + " )" );
var numCorners = Number(fields[7]);
debug( "numCorners " + numCorners );
var m_faceGroupIdx = Number(fields[8]);
var m_materialIdx = Number(fields[9]);
var j = 10;
var edges = new Array();
for( var i = 0; i < numCorners; i++ )
{
// m_vertIdx[i] m_uvwIdx[i] m_normIdx[i]
edges.push( Array( Number(fields[j]), Number(fields[j+1]), Number(fields[j+2]) ) )
j +=3;
}
if( skelname != "none" )
{
skel = Scene.findNode( skelname );
node = skel.findBone( nodename );
}
else
{
node = Scene.findNode( nodename );
}
hitObj = node.getObject();
hitCachedMesh = hitObj.getCachedGeom();
//printing the vertices of the favet
for( var i = 0; i < numCorners; i++ )
{
debug( "v["
+ ( edges[i][0] )
+ "] = "
+ showV( hitCachedMesh.getVertex( edges[i][0] ) )
+ ";" )
}
}
function showV( v )
{
return( "[ ", v.x + ", " + v.y + ", " + v.z + "]" );
}
example of the printout generated by this sample script for a primitive plane
collision point: [41.82, -0.00, 70.685]
skelname none
nodename plane
facetype 1
faceno 0
triangleNo 0
hitUV = ( 0.7091220021247864, 0.146573007106781 )
numCorners 4
v[0] = [-100, 0, 100];
v[1] = [100, 0, 100];
v[3] = [100, 0, -100];
v[2] = [-100, 0, -100];
Converting the hit-point's UV coordinates into painting coordinates
Here is the situation for our example
the plane is 2 meters by 2 meters
the hit point was reported to be [41.82, -0.00, 70.685]
the uv coordinate of the hit point was reported to be ( 0.709, 0.146 )
since the lower-left corner of the plane is at uv coordinate [0,0], this makes sense
the texture image "aikio.jpg" happens to be 800 pixels by 800 pixels
the pixel coordinate for our hit point will be
uvx = 0.709;
uvy = 0.146;
resolutionX = 800;
resolutionY = 800;
pixelX = hitUV.x * resolutionX
pixelY = ( 1 - hitUV.y ) * resolutionY
which gives us the pixel coordinate [567, 683]
confirmed as correct in this picture
Querying hit results, multi-layered hit points
You can query different elements of the collision report
mcjCollider detects the closest hit point, but it also detects the farthest hit point and up to 1024 layers of hit points.
it's a bit like an MRI scanner. This was done for applications like the conversion of a scene into voxels;
Number getNumHits(); this function/slot returns total number of hit points.
String getFacet( DzFacetMesh targetMesh, Number idx );
returns facet[idx] as a tab delimited string in the form: n, m_faceGroupIdx, m_materialIdx, m_vertIdx[0], m_uvwIdx[0],
m_normIdx[0], m_vertIdx[1], m_uvwIdx[1], m_normIdx[1] ... m_vertIdx[n-1], m_uvwIdx[n-1], m_normIdx[n-1],
closest hit point
DzVec3 getHitMinPos();
DzVec3 getHitMinNorm();
Number getHitMinZ();
DzVec3 getHitMinBarycentricUV();
DzVec3 getHitMinUV();
DzNode getHitMinNode();
DzFacetMesh getHitMinMesh();
Number getHitMinFaceNo();
Number getHitMinTriNo();
Number getHitMinFaceType();
farthest hit point
DzVec3 getHitMaxPos();
DzVec3 getHitMaxNorm();
Number getHitMaxZ();
DzVec3 getHitMaxBarycentricUV();
DzVec3 getHitMaxUV();
DzNode getHitMaxNode();
DzFacetMesh getHitMaxMesh();
Number getHitMaxFaceNo();
Number getHitMaxTriNo();
Number getHitMaxFaceType();
up to 1024 hit points (unsorted)
DzVec3 getHitsMaxPos( Number idx );
DzVec3 getHitsMaxNorm( Number idx );
Number getHitsMaxZ( Number idx );
DzVec3 getHitsMaxBarycentricUV( Number idx );
DzVec3 getHitsMaxUV( Number idx );
DzNode getHitsMaxNode( Number idx );
DzFacetMesh getHitsMaxMesh( Number idx );
Number getHitsMaxFaceNo( Number idx );
Number getHitsMaxTriNo( Number idx );
Number getHitsMaxFaceType( Number idx );
collision point world-space
flat facet normal
distance from the collider launch point
barycentric uv coordinate
uv coordinate ( .z = 0 )
node
cached geometry mesh
index of the facet
index within quads for the 2 triangles
0=tri, 1 = quad 2 = poly (DS3 only)
collision point world-space
flat facet normal
distance from the collider launch point
barycentric uv coordinate
uv coordinate ( .z = 0 )
node
cached geometry mesh
index of the facet
index within quads for the 2 triangles
0=tri, 1 = quad 2 = poly (DS3 only)
collision point world-space
flat facet normal
distance from the collider launch point
barycentric uv coordinate
uv coordinate ( .z = 0 )
node
cached geometry mesh
index of the facet
index within quads for the 2 triangles
0=tri, 1 = quad 2 = poly (DS3 only)