Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- macroScript RaycastMatID
- category:"PoC"
- tooltip:"Raycast MatID"
- (
- fn getFaceMatIDFromNode node faceIndex = (
- local matID = undefined
- if faceIndex != undefined do (
- -- Primary method: Standard Mesh
- -- getFaceMatID works reliably on Editable_Mesh nodes.
- if (isKindOf node Editable_Mesh) or (classOf node == TriMesh) then (
- try ( matID = getFaceMatID node faceIndex ) catch ()
- )
- -- If it's a Poly, we usually can't trust the FaceIndex (tri) against the Poly structure directly
- -- without converting the Poly to Mesh first.
- -- So we return undefined, and let the caller handle the layout conversion (via snapshot/fallback).
- )
- matID
- )
- on execute do (
- clearListener()
- local mousePos = mouse.pos
- local viewRay = mapScreenToWorldRay mousePos
- local hits = intersectRayScene viewRay
- if hits.count == 0 then ( print "No hit"; return () )
- local closestNode = undefined
- local closestDist = 1.0e9
- for h in hits do (
- local hitNode = h[1]
- local hitRay = h[2]
- if not hitNode.isHidden do (
- local d = distance viewRay.pos hitRay.pos
- if d < closestDist do (
- closestDist = d
- closestNode = hitNode
- )
- )
- )
- if closestNode == undefined then ( print "No hit (all hidden?)"; return () )
- -- format "Hit: % class=%\n" closestNode.name (classOf closestNode)
- local isVRayProxy = matchPattern ((classOf closestNode) as string) pattern:"*VRayProxy*"
- if not isVRayProxy then (
- -- NORMAL MESH/POLY PATH
- local tStart = timeStamp()
- local exHit = intersectRayEx closestNode viewRay
- local faceIdx = "NA"
- local mID = "NA"
- local status = "FAIL"
- -- Helper to process a successful hit on a node
- fn processHit theNode theHit = (
- local f = theHit[2] -- face index
- local id = getFaceMatIDFromNode theNode f
- #(f, id)
- )
- if exHit != undefined then (
- faceIdx = exHit[2]
- local res = processHit closestNode exHit
- if res[2] != undefined then (
- mID = res[2]
- status = "OK"
- ) else (
- -- Hit existed, but checking MatID on this specific node type failed (e.g. Poly).
- -- Fall through to fallback
- status = "NeedMeshFallback"
- )
- ) else (
- status = "RayMissedGeo"
- )
- -- FALLBACK: If we missed OR if we couldn't get MatID (Poly), try snapshot
- if status == "RayMissedGeo" or status == "NeedMeshFallback" then (
- try (
- -- snapshot creates a NEW temp NODE that is a collapsed Editable Mesh
- local tempMeshNode = snapshot closestNode
- local exHitMesh = intersectRayEx tempMeshNode viewRay
- if exHitMesh != undefined then (
- faceIdx = exHitMesh[2]
- mID = getFaceMatIDFromNode tempMeshNode faceIdx
- status = "OK_ViaMesh"
- ) else (
- status = "RayMissedGeo_EvenAsMesh"
- )
- delete tempMeshNode
- ) catch (
- status = "FallbackException"
- )
- )
- local tEnd = timeStamp()
- local dt = tEnd - tStart
- format "Hit: % class=% dt=%ms face=% matID=%\n" closestNode.name (classOf closestNode) dt faceIdx mID
- ) else (
- -- VRAYPROXY PATH
- local proxyNode = closestNode
- -- APPROACH A: vrayMeshImport()
- local tA0 = timeStamp()
- local resA_Face = "NA"
- local resA_MatID = "NA"
- local resA_Count = 0
- local statusA = "FAIL"
- try (
- local oldSel = selection as array
- select proxyNode
- local imported = undefined
- try ( imported = vrayMeshImport() ) catch ( statusA = "FuncNotFound" )
- if imported != undefined and classOf imported == Array and imported.count > 0 then (
- resA_Count = imported.count
- local meshObj = imported[1]
- meshObj.transform = proxyNode.transform
- local exHit = intersectRayEx meshObj viewRay
- if exHit != undefined then (
- resA_Face = exHit[2]
- local foundID = getFaceMatIDFromNode meshObj resA_Face
- if foundID != undefined then resA_MatID = foundID
- statusA = "OK"
- ) else ( statusA = "MissedImportMesh" )
- delete imported
- ) else (
- if statusA != "FuncNotFound" then statusA = "ImportReturnedEmpty"
- )
- select oldSel
- ) catch ( statusA = "Exception: " + (getCurrentException()) )
- local tA1 = timeStamp()
- local dtA = tA1 - tA0
- format "ApproachA: dt=%ms, face=%, matID=%, importedMeshes=%, status=%\n" dtA resA_Face resA_MatID resA_Count statusA
- -- APPROACH B: Snapshot (Display Mesh + EditPoly + Snapshot)
- local tB0 = timeStamp()
- local resB_Face = "NA"
- local resB_MatID = "NA"
- local statusB = "FAIL"
- local oldDisplay = undefined
- local modAdded = undefined
- try (
- if isProperty proxyNode #display then (
- oldDisplay = proxyNode.display
- proxyNode.display = 3 -- Whole mesh
- )
- modAdded = Edit_Poly()
- addModifier proxyNode modAdded
- -- Create a snapshot NODE (Editable Mesh) of this state
- -- This treats it 'like a normal mesh' for the raycaster
- local tempNode = snapshot proxyNode
- local exHit = intersectRayEx tempNode viewRay
- if exHit != undefined then (
- resB_Face = exHit[2]
- resB_MatID = getFaceMatIDFromNode tempNode resB_Face
- statusB = "OK"
- ) else (
- statusB = "MissedSnapshot"
- )
- delete tempNode
- ) catch ( statusB = "Exception: " + (getCurrentException()) )
- -- Cleanup B
- if modAdded != undefined do (
- local modIndex = undefined
- for m = 1 to proxyNode.modifiers.count do (
- if proxyNode.modifiers[m] == modAdded do modIndex = m
- )
- if modIndex != undefined do deleteModifier proxyNode modIndex
- )
- if oldDisplay != undefined do proxyNode.display = oldDisplay
- local tB1 = timeStamp()
- local dtB = tB1 - tB0
- format "ApproachB: dt=%ms, face=%, matID=%, status=%\n" dtB resB_Face resB_MatID statusB
- )
- )
- )
Advertisement
Add Comment
Please, Sign In to add comment