internal bool UploadCapsuleColliderData(HEU_SessionBase session, CapsuleCollider collider, int inputIndex, HAPI_NodeId parentNodeID, out HAPI_NodeId inputNodeID) { inputNodeID = HEU_Defines.HEU_INVALID_NODE_ID; if (!collider) return false; // Copied from Unreal FKSphylElem::GetElemSolid because exact Unity capsule source code is not available Vector3 sphereCenter = collider.center; float sphereRadius = collider.radius; float sphereLength = collider.height; // Height in Unreal is only the line segment. Height in Unity is the total length, so to get the line length, subtract 2 * rad sphereLength = Mathf.Max(sphereLength - 2 * sphereRadius, 0); int direction = collider.direction; // 0 = X, 1 = Y, 2 = Z. Default is Y // Unreal Y -> Unity X, Unreal Z -> Unity Y int numSides = 6; int numRings = (numSides / 2) + 1; int numVerts = (numSides + 1) * (numRings + 1); // Calculate the vertices for one arc Vector3[] arcVertices = new Vector3[numRings + 1]; for (int ringIdx = 0; ringIdx < numRings + 1; ringIdx++) { float angle; float zOffset; if (ringIdx <= numSides / 4) { angle = ((float) ringIdx / (numRings - 1)) * Mathf.PI; zOffset = 0.5f * sphereLength; } else { angle = ((float)(ringIdx - 1) / (numRings - 1) ) * Mathf.PI; zOffset = -0.5f * sphereLength; } // Note- unit sphere, so position always has mag of one. We can just use it for normal! Vector3 spherePos = new Vector3(); spherePos.x = sphereRadius * Mathf.Sin(angle); spherePos.y = sphereRadius * Mathf.Cos(angle); spherePos.z = 0; arcVertices[ringIdx] = spherePos + new Vector3(0, zOffset, 0); } Vector3 directionRotationEuler = Vector3.zero; if (direction == 1) { // Y axis - This is the default after Unity unit conversion directionRotationEuler = Vector3.zero; } else if (direction == 0) { // X axis - Rotate around Z directionRotationEuler = new Vector3(0, 0, 90); } else if (direction == 2) { // Z axis - Rotate around X directionRotationEuler = new Vector3(90, 0, 0); } Quaternion directionRotation = Quaternion.Euler(directionRotationEuler); // Get the transform matrix for the rotation // Get the capsule vertices by rotating the arc NumSides+1 times float[] vertices = new float[numVerts * 3]; for (int sideIdx = 0; sideIdx < numSides + 1; sideIdx++) { Vector3 arcEuler = new Vector3(0, 360.0f *((float)sideIdx / (float)numSides), 0); Quaternion arcRot = Quaternion.Euler(arcEuler); for (int vertIdx = 0; vertIdx < numRings + 1; vertIdx++) { int vIx = (numRings + 1) * sideIdx + vertIdx; Vector3 arcVertex = arcRot * arcVertices[vertIdx]; arcVertex = directionRotation * arcVertex; Vector3 curPosition = sphereCenter + arcVertex; HEU_HAPIUtility.ConvertPositionUnityToHoudini(curPosition, out vertices[vIx * 3 + 0], out vertices[vIx * 3 + 1], out vertices[vIx * 3 + 2]); } } int numIndices = numSides * numRings * 6; int[] indices = new int[numIndices]; int curIndex = 0; for (int sideIdx = 0; sideIdx < numSides; sideIdx++) { int a0start = (sideIdx + 0) * (numRings + 1); int a1start = (sideIdx + 1) * (numRings + 1); for (int ringIdx = 0; ringIdx < numRings; ringIdx++) { // First tri (reverse winding) indices[curIndex+0] = a0start + ringIdx + 0; indices[curIndex+2] = a1start + ringIdx + 0; indices[curIndex+1] = a0start + ringIdx + 1; curIndex += 3; // Second Tri (reverse winding) indices[curIndex+0] = a1start + ringIdx + 0; indices[curIndex+2] = a1start + ringIdx + 1; indices[curIndex+1] = a0start + ringIdx + 1; curIndex += 3; } } HAPI_NodeId sphereNodeID = -1; string sphereName = string.Format("Sphyl{0}", inputIndex); if (!CreateInputNodeForCollider(session, out sphereNodeID, parentNodeID, inputIndex, sphereName, vertices, indices)) return false; if (!session.CookNode(sphereNodeID, false)) return false; HAPI_NodeId groupNodeID = HEU_Defines.HEU_INVALID_NODE_ID; string groupName = string.Format("group{0}", inputIndex); if (!session.CreateNode(parentNodeID, "groupcreate", groupName, false, out groupNodeID)) { HEU_Logger.LogErrorFormat("Unable to create group SOP node for connecting input assets."); return false; } HAPI_NodeId groupParmID = HEU_Defines.HEU_INVALID_NODE_ID; if (!session.GetParmIDFromName(groupNodeID, "groupname", out groupParmID) || groupParmID == HEU_Defines.HEU_INVALID_NODE_ID) return false; string baseGroupName = GetColliderGroupBaseName(collider, bIsConvex: false, bIsSimple: true); string groupNameStr = string.Format("{0}_capsule{1}", baseGroupName, inputIndex); if (!session.SetParamStringValue(groupNodeID, groupNameStr, groupParmID, 0)) return false; if (!session.ConnectNodeInput(groupNodeID, 0, sphereNodeID)) return false; inputNodeID = groupNodeID; return true; }
internal bool UploadBoxColliderData(HEU_SessionBase session, BoxCollider collider, int inputIndex, HAPI_NodeId parentNodeID, out HAPI_NodeId inputNodeID) { inputNodeID = HEU_Defines.HEU_INVALID_NODE_ID; if (!collider) return false; HAPI_NodeId boxNodeID = HEU_Defines.HEU_INVALID_NODE_ID; string name = string.Format("Box{0}", inputIndex); Vector3 center = HEU_HAPIUtility.ConvertPositionUnityToHoudini(collider.center); Vector3 size = HEU_HAPIUtility.ConvertScaleUnityToHoudini(collider.size); if (!session.CreateNode(parentNodeID, "box", null, false, out boxNodeID)) { HEU_Logger.LogErrorFormat("Unable to create merge box node for connecting input assets."); return false; } string sizeParamName = "size"; if (!session.SetParamFloatValue(boxNodeID, sizeParamName, 0, size.x)) return false; if (!session.SetParamFloatValue(boxNodeID, sizeParamName, 1, size.y)) return false; if (!session.SetParamFloatValue(boxNodeID, sizeParamName, 2, size.z)) return false; string transformParamName = "t"; if (!session.SetParamFloatValue(boxNodeID, transformParamName, 0, center.x)) return false; if (!session.SetParamFloatValue(boxNodeID, transformParamName, 1, center.y)) return false; if (!session.SetParamFloatValue(boxNodeID, transformParamName, 2, center.z)) return false; if (!session.CookNode(boxNodeID, false)) return false; HAPI_NodeId groupNodeID = HEU_Defines.HEU_INVALID_NODE_ID; string groupName = string.Format("group{0}", inputIndex); if (!session.CreateNode(parentNodeID, "groupcreate", groupName, false, out groupNodeID)) { HEU_Logger.LogErrorFormat("Unable to create group SOP node for connecting input assets."); return false; } HAPI_NodeId groupParmID = HEU_Defines.HEU_INVALID_NODE_ID; if (!session.GetParmIDFromName(groupNodeID, "groupname", out groupParmID) || groupParmID == HEU_Defines.HEU_INVALID_NODE_ID) return false; string baseGroupName = GetColliderGroupBaseName(collider, bIsConvex: false, bIsSimple: true); string groupNameStr = string.Format("{0}_box{1}", baseGroupName, inputIndex); if (!session.SetParamStringValue(groupNodeID, groupNameStr, groupParmID, 0)) return false; if (!session.ConnectNodeInput(groupNodeID, 0, boxNodeID)) return false; inputNodeID = groupNodeID; return true; }
internal bool UploadSphereColliderData(HEU_SessionBase session, SphereCollider collider, int inputIndex, HAPI_NodeId parentNodeID, out HAPI_NodeId inputNodeID) { inputNodeID = HEU_Defines.HEU_INVALID_NODE_ID; if (!collider) return false; Vector3 center = HEU_HAPIUtility.ConvertPositionUnityToHoudini(collider.center); float radius = collider.radius; HAPI_NodeId sphereNodeID = HEU_Defines.HEU_INVALID_NODE_ID; string name = string.Format("Sphere{0}", inputIndex); if (!session.CreateNode(parentNodeID, "sphere", null, false, out sphereNodeID)) { HEU_Logger.LogErrorFormat("Unable to create merge box node for connecting input assets."); return false; } string radParamName = "rad"; if (!session.SetParamFloatValue(sphereNodeID, radParamName, 0, radius)) return false; if (!session.SetParamFloatValue(sphereNodeID, radParamName, 1, radius)) return false; if (!session.SetParamFloatValue(sphereNodeID, radParamName, 2, radius)) return false; string transformParamName = "t"; if (!session.SetParamFloatValue(sphereNodeID, transformParamName, 0, center.x)) return false; if (!session.SetParamFloatValue(sphereNodeID, transformParamName, 1, center.y)) return false; if (!session.SetParamFloatValue(sphereNodeID, transformParamName, 2, center.z)) return false; string typeParamName = "type"; if (!session.SetParamIntValue(sphereNodeID, typeParamName, 0, 1)) return false; if (!session.CookNode(sphereNodeID, false)) return false; HAPI_NodeId groupNodeID = HEU_Defines.HEU_INVALID_NODE_ID; string groupName = string.Format("group{0}", inputIndex); if (!session.CreateNode(parentNodeID, "groupcreate", groupName, false, out groupNodeID)) { HEU_Logger.LogErrorFormat("Unable to create group SOP node for connecting input assets."); return false; } HAPI_NodeId groupParmID = HEU_Defines.HEU_INVALID_NODE_ID; if (!session.GetParmIDFromName(groupNodeID, "groupname", out groupParmID) || groupParmID == HEU_Defines.HEU_INVALID_NODE_ID) return false; string baseGroupName = GetColliderGroupBaseName(collider, bIsConvex: false, bIsSimple: true); string groupNameStr = string.Format("{0}_sphere{1}", baseGroupName, inputIndex); if (!session.SetParamStringValue(groupNodeID, groupNameStr, groupParmID, 0)) return false; if (!session.ConnectNodeInput(groupNodeID, 0, sphereNodeID)) return false; inputNodeID = groupNodeID; return true; }
internal bool UploadMeshColliderData(HEU_SessionBase session, MeshCollider collider, int inputIndex, HAPI_NodeId parentNodeID, out HAPI_NodeId inputNodeID) { inputNodeID = HEU_Defines.HEU_INVALID_NODE_ID; if (!collider) return false; Mesh mesh = collider.sharedMesh; Vector3[] vertices = mesh.vertices; int numSubmeshes = mesh.subMeshCount; List<int> indices = new List<int>(); for (int i = 0; i < numSubmeshes; i++) { int[] indicesForSubmesh = mesh.GetIndices(i); indices.AddRange(indicesForSubmesh); } int[] indicesArr = indices.ToArray(); float[] verticesArr = new float[vertices.Length * 3]; for (int i = 0; i < vertices.Length; i++) { HEU_HAPIUtility.ConvertPositionUnityToHoudini(vertices[i], out verticesArr[i * 3 + 0], out verticesArr[i * 3 + 1], out verticesArr[i * 3 + 2]); } HAPI_NodeId meshNodeID = -1; string meshName = string.Format("MeshCollider{0}", inputIndex); if (!CreateInputNodeForCollider(session, out meshNodeID, parentNodeID, inputIndex, meshName, verticesArr, indicesArr)) return false; if (!session.CookNode(meshNodeID, false)) return false; HAPI_NodeId groupNodeID = HEU_Defines.HEU_INVALID_NODE_ID; string groupName = string.Format("group{0}", inputIndex); if (!session.CreateNode(parentNodeID, "groupcreate", groupName, false, out groupNodeID)) { HEU_Logger.LogErrorFormat("Unable to create group SOP node for connecting input assets."); return false; } HAPI_NodeId groupParmID = HEU_Defines.HEU_INVALID_NODE_ID; if (!session.GetParmIDFromName(groupNodeID, "groupname", out groupParmID) || groupParmID == HEU_Defines.HEU_INVALID_NODE_ID) return false; bool isConvex = collider.convex; string baseGroupName = GetColliderGroupBaseName(collider, bIsConvex: isConvex, bIsSimple: false); string groupNameStr = string.Format("{0}_mesh{1}", baseGroupName, inputIndex); if (!session.SetParamStringValue(groupNodeID, groupNameStr, groupParmID, 0)) return false; if (!session.ConnectNodeInput(groupNodeID, 0, meshNodeID)) return false; inputNodeID = groupNodeID; return true; }