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

    1. figure name : example: "shi6f_8206", if the collided object is not a figure, then figure name will be "none",
    2. 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".
    3. facet type: 0 = triangle, 1 = square, 2 = polygon (DS3 only) )
    4. facet index: example: 580
    5. 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)