#ifndef COLLISIONMATERIAL_INCLUDE #define COLLISIONMATERIAL_INCLUDE struct collisionMaterial { float dynamicFriction; float staticFriction; float rollingFriction; float stickiness; float stickDistance; int frictionCombine; int stickinessCombine; int rollingContacts; }; StructuredBuffer collisionMaterialIndices; StructuredBuffer collisionMaterials; collisionMaterial EmptyCollisionMaterial() { collisionMaterial m; m.dynamicFriction = 0; m.staticFriction = 0; m.rollingFriction = 0; m.stickiness = 0; m.stickDistance = 0; m.frictionCombine = 0; m.stickinessCombine = 0; m.rollingContacts = 0; return m; } collisionMaterial CombineWith(collisionMaterial a, collisionMaterial b) { collisionMaterial result; int frictionCombineMode = max(a.frictionCombine, b.frictionCombine); int stickCombineMode = max(a.stickinessCombine, b.stickinessCombine); switch (frictionCombineMode) { case 0: default: result.dynamicFriction = (a.dynamicFriction + b.dynamicFriction) * 0.5f; result.staticFriction = (a.staticFriction + b.staticFriction) * 0.5f; result.rollingFriction = (a.rollingFriction + b.rollingFriction) * 0.5f; break; case 1: result.dynamicFriction = min(a.dynamicFriction, b.dynamicFriction); result.staticFriction = min(a.staticFriction, b.staticFriction); result.rollingFriction = min(a.rollingFriction, b.rollingFriction); break; case 2: result.dynamicFriction = a.dynamicFriction * b.dynamicFriction; result.staticFriction = a.staticFriction * b.staticFriction; result.rollingFriction = a.rollingFriction * b.rollingFriction; break; case 3: result.dynamicFriction = max(a.dynamicFriction, b.dynamicFriction); result.staticFriction = max(a.staticFriction, b.staticFriction); result.rollingFriction = max(a.rollingFriction, b.rollingFriction); break; } switch (stickCombineMode) { case 0: default: result.stickiness = (a.stickiness + b.stickiness) * 0.5f; break; case 1: result.stickiness = min(a.stickiness, b.stickiness); break; case 2: result.stickiness = a.stickiness * b.stickiness; break; case 3: result.stickiness = max(a.stickiness, b.stickiness); break; } result.stickDistance = max(a.stickDistance, b.stickDistance); result.rollingContacts = a.rollingContacts | b.rollingContacts; return result; } collisionMaterial CombineCollisionMaterials(int materialA, int materialB) { // Combine collision materials: collisionMaterial combined; if (materialA >= 0 && materialB >= 0) combined = CombineWith(collisionMaterials[materialA], collisionMaterials[materialB]); else if (materialA >= 0) combined = collisionMaterials[materialA]; else if (materialB >= 0) combined = collisionMaterials[materialB]; else combined = EmptyCollisionMaterial(); return combined; } #endif