internal AuthInfo(UserInfo userInfo) { this = default; fixed(AuthInfo *self = &this) { UnsafeUtility.MemCpy(self->m_IdentityUrl, userInfo.m_IdentityUrl, 256 * sizeof(char)); UnsafeUtility.MemCpy(self->m_AccessToken, userInfo.m_AccessToken, 256 * sizeof(char)); UnsafeUtility.MemCpy(self->m_UserId, userInfo.m_UserId, 256 * sizeof(char)); } }
public unsafe void Execute() { var bodies = World.Bodies.GetUnsafeReadOnlyPtr(); var motionDatas = (MotionData *)World.MotionDatas.GetUnsafeReadOnlyPtr(); var motionVelocities = (MotionVelocity *)World.MotionVelocities.GetUnsafeReadOnlyPtr(); var joints = World.Joints.GetUnsafeReadOnlyPtr(); Plugin.HP_SyncWorldIn( WorldIndex, bodies, World.NumBodies, UnsafeUtility.SizeOf <RigidBody>(), motionDatas, World.NumDynamicBodies, sizeof(MotionData), motionVelocities, World.NumDynamicBodies, sizeof(MotionVelocity), joints, World.NumJoints, UnsafeUtility.SizeOf <Joint>()); }
public void Dispose() { if (m_WorldAllocated) { // Destroy world only if it was allocated Plugin.HP_DestroyWorld(WorldIndex); } if (InputVelocities.IsCreated) { InputVelocities.Dispose(); } unsafe { UnsafeUtility.Free(StepContext, Allocator.Persistent); } }
public SimulationContext(HavokConfiguration config) { // Unlock the plugin if it hasn't already been done. // If it remains locked, the simulation will do nothing. Plugin.EnsureUnlocked(); TimeStep = default; InputVelocities = default; Camera = default; unsafe { // Allocate this at a fixed memory location. The plugin writes to it. StepContext = (HavokSimulation.StepContext *)UnsafeUtility.Malloc(sizeof(HavokSimulation.StepContext), 16, Allocator.Persistent); UnsafeUtility.MemClear(StepContext, sizeof(HavokSimulation.StepContext)); VisualDebuggerEnabled = config.VisualDebugger.Enable != 0; WorldIndex = Plugin.HP_AllocateWorld(ref config, StepContext); m_WorldAllocated = true; } }
// Create a compound collider containing an array of other colliders. // The source colliders are copied into the compound, so that it becomes one blob. public static unsafe BlobAssetReference <Collider> Create(NativeArray <ColliderBlobInstance> children) { if (children.Length == 0) { throw new ArgumentException(); } // Get the total required memory size for the compound plus all its children, // and the combined filter of all children // TODO: Verify that the size is enough int totalSize = Math.NextMultipleOf16(UnsafeUtility.SizeOf <CompoundCollider>()); CollisionFilter filter = children[0].Collider.Value.Filter; foreach (var child in children) { totalSize += Math.NextMultipleOf16(child.Collider.Value.MemorySize); filter = CollisionFilter.CreateUnion(filter, child.Collider.Value.Filter); } totalSize += (children.Length + BoundingVolumeHierarchy.Constants.MaxNumTreeBranches) * UnsafeUtility.SizeOf <BoundingVolumeHierarchy.Node>(); // Allocate the collider var compoundCollider = (CompoundCollider *)UnsafeUtility.Malloc(totalSize, 16, Allocator.Temp); UnsafeUtility.MemClear(compoundCollider, totalSize); compoundCollider->m_Header.Type = ColliderType.Compound; compoundCollider->m_Header.CollisionType = CollisionType.Composite; compoundCollider->m_Header.Version = 0; compoundCollider->m_Header.Magic = 0xff; compoundCollider->m_Header.Filter = filter; // Initialize children array Child *childrenPtr = (Child *)((byte *)compoundCollider + UnsafeUtility.SizeOf <CompoundCollider>()); compoundCollider->m_ChildrenBlob.Offset = (int)((byte *)childrenPtr - (byte *)(&compoundCollider->m_ChildrenBlob.Offset)); compoundCollider->m_ChildrenBlob.Length = children.Length; byte *end = (byte *)childrenPtr + UnsafeUtility.SizeOf <Child>() * children.Length; end = (byte *)Math.NextMultipleOf16((ulong)end); // Copy children for (int i = 0; i < children.Length; i++) { Collider *collider = (Collider *)children[i].Collider.GetUnsafePtr(); UnsafeUtility.MemCpy(end, collider, collider->MemorySize); childrenPtr[i].m_ColliderOffset = (int)(end - (byte *)(&childrenPtr[i].m_ColliderOffset)); childrenPtr[i].CompoundFromChild = children[i].CompoundFromChild; end += Math.NextMultipleOf16(collider->MemorySize); } // Build mass properties compoundCollider->MassProperties = compoundCollider->BuildMassProperties(); // Build bounding volume int numNodes = compoundCollider->BuildBoundingVolume(out NativeArray <BoundingVolumeHierarchy.Node> nodes); int bvhSize = numNodes * UnsafeUtility.SizeOf <BoundingVolumeHierarchy.Node>(); compoundCollider->m_BvhNodesBlob.Offset = (int)(end - (byte *)(&compoundCollider->m_BvhNodesBlob.Offset)); compoundCollider->m_BvhNodesBlob.Length = numNodes; UnsafeUtility.MemCpy(end, nodes.GetUnsafeReadOnlyPtr(), bvhSize); end += bvhSize; nodes.Dispose(); // Copy to blob asset int usedSize = (int)(end - (byte *)compoundCollider); UnityEngine.Assertions.Assert.IsTrue(usedSize < totalSize); compoundCollider->MemorySize = usedSize; byte[] bytes = new byte[usedSize]; Marshal.Copy((IntPtr)compoundCollider, bytes, 0, usedSize); var blob = BlobAssetReference <Collider> .Create(bytes); UnsafeUtility.Free(compoundCollider, Allocator.Temp); return(blob); }
public static unsafe BlobAssetReference <Collider> Create(NativeArray <float3> vertices, NativeArray <int3> triangles, CollisionFilter filter, Material material) { // Copy vertices var tempVertices = new NativeArray <float3>(vertices, Allocator.Temp); // Triangle indices - needed for WeldVertices var tempIndices = new NativeArray <int>(triangles.Length * 3, Allocator.Temp); for (int iTriangle = 0; iTriangle < triangles.Length; iTriangle++) { if (triangles[iTriangle][0] >= 0 && triangles[iTriangle][0] < vertices.Length && triangles[iTriangle][1] >= 0 && triangles[iTriangle][1] < vertices.Length && triangles[iTriangle][2] >= 0 && triangles[iTriangle][2] < vertices.Length) { tempIndices[iTriangle * 3] = triangles[iTriangle][0]; tempIndices[iTriangle * 3 + 1] = triangles[iTriangle][1]; tempIndices[iTriangle * 3 + 2] = triangles[iTriangle][2]; } else { throw new ArgumentException("Tried to create a MeshCollider with indices referencing outside vertex array"); } } // Build connectivity and primitives NativeList <float3> uniqueVertices = MeshConnectivityBuilder.WeldVertices(tempIndices, tempVertices); var tempTriangleIndices = new NativeArray <int3>(triangles.Length, Allocator.Temp); UnsafeUtility.MemCpy(tempTriangleIndices.GetUnsafePtr(), tempIndices.GetUnsafePtr(), tempIndices.Length * UnsafeUtility.SizeOf <int>()); var connectivity = new MeshConnectivityBuilder(tempTriangleIndices, uniqueVertices); NativeList <MeshConnectivityBuilder.Primitive> primitives = connectivity.EnumerateQuadDominantGeometry(tempTriangleIndices, uniqueVertices); // Build bounding volume hierarchy int nodeCount = math.max(primitives.Length * 2 + 1, 2); // We need at least two nodes - an "invalid" node and a root node. var nodes = new NativeArray <BoundingVolumeHierarchy.Node>(nodeCount, Allocator.Temp); int numNodes = 0; { // Prepare data for BVH var points = new NativeList <BoundingVolumeHierarchy.PointAndIndex>(primitives.Length, Allocator.Temp); var aabbs = new NativeArray <Aabb>(primitives.Length, Allocator.Temp); for (int i = 0; i < primitives.Length; i++) { MeshConnectivityBuilder.Primitive p = primitives[i]; // Skip degenerate triangles if (MeshConnectivityBuilder.IsTriangleDegenerate(p.Vertices[0], p.Vertices[1], p.Vertices[2])) { continue; } aabbs[i] = Aabb.CreateFromPoints(p.Vertices); points.Add(new BoundingVolumeHierarchy.PointAndIndex { Position = aabbs[i].Center, Index = i }); } var bvh = new BoundingVolumeHierarchy(nodes); bvh.Build(points.AsArray(), aabbs, out numNodes, useSah: true); } // Build mesh sections BoundingVolumeHierarchy.Node *nodesPtr = (BoundingVolumeHierarchy.Node *)nodes.GetUnsafePtr(); MeshBuilder.TempSection sections = MeshBuilder.BuildSections(nodesPtr, numNodes, primitives); // Allocate collider int meshDataSize = Mesh.CalculateMeshDataSize(numNodes, sections.Ranges); int totalColliderSize = Math.NextMultipleOf(sizeof(MeshCollider), 16) + meshDataSize; MeshCollider *meshCollider = (MeshCollider *)UnsafeUtility.Malloc(totalColliderSize, 16, Allocator.Temp); // Initialize it { UnsafeUtility.MemClear(meshCollider, totalColliderSize); meshCollider->MemorySize = totalColliderSize; meshCollider->m_Header.Type = ColliderType.Mesh; meshCollider->m_Header.CollisionType = CollisionType.Composite; meshCollider->m_Header.Version += 1; meshCollider->m_Header.Magic = 0xff; ref var mesh = ref meshCollider->Mesh; mesh.Init(nodesPtr, numNodes, sections, filter, material); // Calculate combined filter meshCollider->m_Header.Filter = mesh.Sections.Length > 0 ? mesh.Sections[0].Filters[0] : CollisionFilter.Default; for (int i = 0; i < mesh.Sections.Length; ++i) { for (var j = 0; j < mesh.Sections[i].Filters.Length; ++j) { var f = mesh.Sections[i].Filters[j]; meshCollider->m_Header.Filter = CollisionFilter.CreateUnion(meshCollider->m_Header.Filter, f); } } meshCollider->m_Aabb = meshCollider->Mesh.BoundingVolumeHierarchy.Domain; meshCollider->NumColliderKeyBits = meshCollider->Mesh.NumColliderKeyBits; }