static void UpdateModel(FoamModel Model, int FrameIndex) { if (Model.Animations == null) { return; } //Matrix4x4 ParentRotMat = Matrix4x4.CreateFromYawPitchRoll(0, -Pi / 2, 0); foreach (var Msh in Model.Meshes) { List <Vertex3> Verts = new List <Vertex3>(); if (Msh.BoneInformation == null) { continue; } foreach (var Index in Msh.Indices) { FoamVertex3 Vert = Msh.Vertices[Index]; FoamBoneInfo Info = Msh.BoneInformation[Index]; FoamBone Bone1 = Model.Bones[Info.Bone1]; // TODO: Weights Matrix4x4 BindWorld = Bone1.BindMatrix; Matrix4x4 WorldTrans = Model.CalcWorldTransform(0, FrameIndex, Info.Bone1); Vector3 Pos = Vector3.Transform(Vert.Position, BindWorld * WorldTrans); // TODO: Flip? Verts.Add(new Vertex3(Pos, Vert.UV)); } Mesh *RayMesh = ((Model)Msh.Userdata).meshes; Raylib.UnloadMesh(*RayMesh); *RayMesh = Raylib.GenMeshRaw(Verts.ToArray()); } }
public ConvexMeshLeafProcessor(MeshCollider *meshCollider) { m_Mesh = &meshCollider->Mesh; m_NumColliderKeyBits = meshCollider->NumColliderKeyBits; }
public unsafe static int Main() { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh picking"); // Define the camera to look into our 3d world Camera3D camera; camera.position = new Vector3(20.0f, 20.0f, 20.0f); // Camera3D position camera.target = new Vector3(0.0f, 8.0f, 0.0f); // Camera3D looking at point camera.up = new Vector3(0.0f, 1.6f, 0.0f); // Camera3D up vector (rotation towards target) camera.fovy = 45.0f; // Camera3D field-of-view Y camera.type = CAMERA_PERSPECTIVE; // Camera3D mode type Ray ray = new Ray(); // Picking ray Model tower = LoadModel("resources/models/turret.obj"); // Load OBJ model Texture2D texture = LoadTexture("resources/models/turret_diffuse.png"); // Load model texture Utils.SetMaterialTexture(ref tower, 0, MAP_ALBEDO, ref texture); // Set map diffuse texture Vector3 towerPos = new Vector3(0.0f, 0.0f, 0.0f); // Set model position Mesh * meshes = (Mesh *)tower.meshes.ToPointer(); BoundingBox towerBBox = MeshBoundingBox(meshes[0]); // Get mesh bounding box bool hitMeshBBox = false; bool hitTriangle = false; // Test triangle Vector3 ta = new Vector3(-25.0f, 0.5f, 0.0f); Vector3 tb = new Vector3(-4.0f, 2.5f, 1.0f); Vector3 tc = new Vector3(-8.0f, 6.5f, 0.0f); Vector3 bary = new Vector3(0.0f, 0.0f, 0.0f); SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //---------------------------------------------------------------------------------- // Main game loop //-------------------------------------------------------------------------------------- while (!WindowShouldClose()) // Detect window close button or ESC key { //---------------------------------------------------------------------------------- // Update //---------------------------------------------------------------------------------- UpdateCamera(ref camera); // Update camera // Display information about closest hit RayHitInfo nearestHit = new RayHitInfo(); string hitObjectName = "None"; nearestHit.distance = FLT_MAX; nearestHit.hit = false; Color cursorColor = WHITE; // Get ray and test against ground, triangle, and mesh ray = GetMouseRay(GetMousePosition(), camera); // Check ray collision aginst ground plane RayHitInfo groundHitInfo = GetCollisionRayGround(ray, 0.0f); if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) { nearestHit = groundHitInfo; cursorColor = GREEN; hitObjectName = "Ground"; } // Check ray collision against test triangle RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, ta, tb, tc); if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) { nearestHit = triHitInfo; cursorColor = PURPLE; hitObjectName = "Triangle"; bary = Vector3Barycenter(nearestHit.position, ta, tb, tc); hitTriangle = true; } else { hitTriangle = false; } RayHitInfo meshHitInfo = new RayHitInfo(); // Check ray collision against bounding box first, before trying the full ray-mesh test if (CheckCollisionRayBox(ray, towerBBox)) { hitMeshBBox = true; // Check ray collision against model // NOTE: It considers model.transform matrix! meshHitInfo = GetCollisionRayModel(ray, tower); if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) { nearestHit = meshHitInfo; cursorColor = ORANGE; hitObjectName = "Mesh"; } } hitMeshBBox = false; //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); BeginMode3D(camera); // Draw the tower // WARNING: If scale is different than 1.0f, // not considered by GetCollisionRayModel() DrawModel(tower, towerPos, 1.0f, WHITE); // Draw the test triangle DrawLine3D(ta, tb, PURPLE); DrawLine3D(tb, tc, PURPLE); DrawLine3D(tc, ta, PURPLE); // Draw the mesh bbox if we hit it if (hitMeshBBox) { DrawBoundingBox(towerBBox, LIME); } // If we hit something, draw the cursor at the hit point if (nearestHit.hit) { DrawCube(nearestHit.position, 0.3f, 0.3f, 0.3f, cursorColor); DrawCubeWires(nearestHit.position, 0.3f, 0.3f, 0.3f, RED); Vector3 normalEnd; normalEnd.X = nearestHit.position.X + nearestHit.normal.X; normalEnd.Y = nearestHit.position.Y + nearestHit.normal.Y; normalEnd.Z = nearestHit.position.Z + nearestHit.normal.Z; DrawLine3D(nearestHit.position, normalEnd, RED); } DrawRay(ray, MAROON); DrawGrid(10, 10.0f); EndMode3D(); // Draw some debug GUI text DrawText(string.Format("Hit Object: {0}", hitObjectName), 10, 50, 10, BLACK); if (nearestHit.hit) { int ypos = 70; var x = string.Format("Distance: {0:000.00}", nearestHit.distance); DrawText(string.Format("Distance: {0:000.00}", nearestHit.distance), 10, ypos, 10, BLACK); DrawText(string.Format("Hit Pos: {0:000.00} {1:000.00} {2:000.00}", nearestHit.position.X, nearestHit.position.Y, nearestHit.position.Z), 10, ypos + 15, 10, BLACK); DrawText(string.Format("Hit Norm: {0:000.00} {1:000.00} {2:000.00}", nearestHit.normal.X, nearestHit.normal.Y, nearestHit.normal.Z), 10, ypos + 30, 10, BLACK); if (hitTriangle) { DrawText(string.Format("Barycenter:{0:000.00} {1:000.00} {2:000.00}", bary.X, bary.Y, bary.Z), 10, ypos + 45, 10, BLACK); } } DrawText("Use Mouse to Move Camera", 10, 430, 10, GRAY); DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- UnloadModel(tower); // Unload model UnloadTexture(texture); // Unload texture CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return(0); }
public unsafe static int Main() { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; SetConfigFlags(ConfigFlag.FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available) InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material"); // Define the camera to look into our 3d world Camera3D camera = new Camera3D(); camera.position = new Vector3(4.0f, 4.0f, 4.0f); camera.target = new Vector3(0.0f, 0.5f, 0.0f); camera.up = new Vector3(0.0f, 1.0f, 0.0f); camera.fovy = 45.0f; camera.type = CAMERA_PERSPECTIVE; // Load model and PBR material Model model = LoadModel("resources/pbr/trooper.obj"); // Unsafe pointers into model arrays. Material *materials = (Material *)model.materials.ToPointer(); Mesh * meshes = (Mesh *)model.meshes.ToPointer(); // Mesh tangents are generated... and uploaded to GPU // NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO MeshTangents(ref meshes[0]); UnloadMaterial(materials[0]); // get rid of default material materials[0] = LoadMaterialPBR(new Color(255, 255, 255, 255), 1.0f, 1.0f); // Define lights attributes // NOTE: Shader is passed to every light on creation to define shader bindings internally CreateLight(LightType.LIGHT_POINT, new Vector3(LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Color(255, 0, 0, 255), materials[0].shader); CreateLight(LightType.LIGHT_POINT, new Vector3(0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE), new Vector3(0.0f, 0.0f, 0.0f), new Color(0, 255, 0, 255), materials[0].shader); CreateLight(LightType.LIGHT_POINT, new Vector3(-LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Color(0, 0, 255, 255), materials[0].shader); CreateLight(LightType.LIGHT_DIRECTIONAL, new Vector3(0.0f, LIGHT_HEIGHT * 2.0f, -LIGHT_DISTANCE), new Vector3(0.0f, 0.0f, 0.0f), new Color(255, 0, 255, 255), materials[0].shader); SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- UpdateCamera(ref camera); // Update camera // Send to material PBR shader camera view position float[] cameraPos = { camera.position.X, camera.position.Y, camera.position.Z }; int * locs = (int *)materials[0].shader.locs.ToPointer(); Utils.SetShaderValue(materials[0].shader, (int)ShaderLocationIndex.LOC_VECTOR_VIEW, cameraPos, ShaderUniformDataType.UNIFORM_VEC3); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); BeginMode3D(camera); DrawModel(model, Vector3Zero(), 1.0f, WHITE); DrawGrid(10, 1.0f); EndMode3D(); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- // Shaders and textures must be unloaded by user, // they could be in use by other models MaterialMap *maps = (MaterialMap *)materials[0].maps.ToPointer(); UnloadTexture(maps[(int)MaterialMapType.MAP_ALBEDO].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_NORMAL].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_METALNESS].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_ROUGHNESS].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_OCCLUSION].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_IRRADIANCE].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_PREFILTER].texture); UnloadTexture(maps[(int)MaterialMapType.MAP_BRDF].texture); UnloadShader(materials[0].shader); UnloadModel(model); // Unload skybox model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return(0); }
public MeshLeafProcessor(MeshCollider *mesh) { m_Mesh = &mesh->Mesh; m_NumColliderKeyBits = mesh->NumColliderKeyBits; m_NumKeys = 0; }
public void AddColliderKeys(ColliderKey *keys, int count) { var colliderKeys = new ColliderKeyPair { ColliderKeyA = m_ConvexColliderKey, ColliderKeyB = m_ConvexColliderKey }; CollisionFilter filter = m_ConvexColliderA->Filter; // Collide the convex A with all overlapping leaves of B switch (m_CompositeColliderB->Type) { // Special case meshes (since we know all polygons will be built on the fly) case ColliderType.Mesh: { Mesh *mesh = &((MeshCollider *)m_CompositeColliderB)->Mesh; uint numMeshKeyBits = mesh->NumColliderKeyBits; var polygon = new PolygonCollider(); polygon.InitEmpty(); for (int i = 0; i < count; i++) { ColliderKey compositeKey = m_CompositeColliderKeyPath.GetLeafKey(keys[i]); uint meshKey = compositeKey.Value >> (32 - (int)numMeshKeyBits); if (mesh->GetPolygon(meshKey, filter, ref polygon)) { if (m_Flipped) { colliderKeys.ColliderKeyA = compositeKey; } else { colliderKeys.ColliderKeyB = compositeKey; } switch (m_ConvexColliderA->CollisionType) { case CollisionType.Convex: ConvexConvex( m_Context, colliderKeys, m_ConvexColliderA, (Collider *)&polygon, m_WorldFromA, m_WorldFromB, m_CollisionTolerance, m_Flipped); break; case CollisionType.Terrain: TerrainConvex( m_Context, colliderKeys, m_ConvexColliderA, (Collider *)&polygon, m_WorldFromA, m_WorldFromB, m_CollisionTolerance, m_Flipped); break; default: // GetLeaf() may not return a composite collider throw new NotImplementedException(); } } } } break; // General case for all other composites (compounds, compounds of meshes, etc) default: { for (int i = 0; i < count; i++) { ColliderKey compositeKey = m_CompositeColliderKeyPath.GetLeafKey(keys[i]); m_CompositeColliderB->GetLeaf(compositeKey, out ChildCollider leaf); if (CollisionFilter.IsCollisionEnabled(filter, leaf.Collider->Filter)) // TODO: shouldn't be needed if/when filtering is done fully by the BVH query { if (m_Flipped) { colliderKeys.ColliderKeyA = compositeKey; } else { colliderKeys.ColliderKeyB = compositeKey; } MTransform worldFromLeafB = Mul(m_WorldFromB, new MTransform(leaf.TransformFromChild)); switch (leaf.Collider->CollisionType) { case CollisionType.Convex: ConvexConvex( m_Context, colliderKeys, m_ConvexColliderA, leaf.Collider, m_WorldFromA, worldFromLeafB, m_CollisionTolerance, m_Flipped); break; case CollisionType.Terrain: ConvexTerrain( m_Context, colliderKeys, m_ConvexColliderA, leaf.Collider, m_WorldFromA, worldFromLeafB, m_CollisionTolerance, m_Flipped); break; default: // GetLeaf() may not return a composite collider throw new NotImplementedException(); } } } } break; } }
public unsafe static int Main() { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; SetConfigFlags(ConfigFlag.FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available) InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material"); // Define the camera to look into our 3d world Camera3D camera = new Camera3D(); camera.position = new Vector3(4.0f, 4.0f, 4.0f); camera.target = new Vector3(0.0f, 0.5f, 0.0f); camera.up = new Vector3(0.0f, 1.0f, 0.0f); camera.fovy = 45.0f; camera.type = CAMERA_PERSPECTIVE; // Load model and PBR material Model model = LoadModel("resources/pbr/trooper.obj"); // Unsafe pointers into model arrays. Material *materials = (Material *)model.materials.ToPointer(); Mesh * meshes = (Mesh *)model.meshes.ToPointer(); materials[0] = LoadMaterialPBR(new Color(255, 255, 255, 255), 1.0f, 1.0f); // Define lights attributes // NOTE: Shader is passed to every light on creation to define shader bindings internally CreateLight(0, LightType.LIGHT_POINT, new Vector3(LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Color(255, 0, 0, 255), materials[0].shader); CreateLight(1, LightType.LIGHT_POINT, new Vector3(0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE), new Vector3(0.0f, 0.0f, 0.0f), new Color(0, 255, 0, 255), materials[0].shader); CreateLight(2, LightType.LIGHT_POINT, new Vector3(-LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Color(0, 0, 255, 255), materials[0].shader); CreateLight(3, LightType.LIGHT_DIRECTIONAL, new Vector3(0.0f, LIGHT_HEIGHT * 2.0f, -LIGHT_DISTANCE), new Vector3(0.0f, 0.0f, 0.0f), new Color(255, 0, 255, 255), materials[0].shader); SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- UpdateCamera(ref camera); // Update camera // Send to material PBR shader camera view position float[] cameraPos = { camera.position.X, camera.position.Y, camera.position.Z }; int * locs = (int *)materials[0].shader.locs.ToPointer(); Utils.SetShaderValue(materials[0].shader, (int)ShaderLocationIndex.LOC_VECTOR_VIEW, cameraPos, ShaderUniformDataType.UNIFORM_VEC3); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); BeginMode3D(camera); DrawModel(model, Vector3.Zero, 1.0f, WHITE); DrawGrid(10, 1.0f); EndMode3D(); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- UnloadMaterial(materials[0]); // Unload material: shader and textures UnloadModel(model); // Unload model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return(0); }
public unsafe static int Main() { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [models] example - models loading"); // Define the camera to look into our 3d world Camera3D camera = new Camera3D(); camera.position = new Vector3(50.0f, 50.0f, 50.0f); // Camera position camera.target = new Vector3(0.0f, 10.0f, 0.0f); // Camera looking at point camera.up = new Vector3(0.0f, 1.0f, 0.0f); // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y camera.type = CAMERA_PERSPECTIVE; // Camera mode type Model model = LoadModel("resources/models/castle.obj"); // Load model Texture2D texture = LoadTexture("resources/models/castle_diffuse.png"); // Load model texture // Set map diffuse texture Utils.SetMaterialTexture(ref model, 0, MAP_ALBEDO, ref texture); Vector3 position = new Vector3(0.0f, 0.0f, 0.0f); // Set model position Mesh * meshes = (Mesh *)model.meshes.ToPointer(); BoundingBox bounds = MeshBoundingBox(meshes[0]); // Set model bounds // NOTE: bounds are calculated from the original size of the model, // if model is scaled on drawing, bounds must be also scaled SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode bool selected = false; // Selected object flag SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- UpdateCamera(ref camera); // Load new models/textures on dragref if (IsFileDropped()) { int count = 0; string[] droppedFiles = Utils.MarshalDroppedFiles(ref count); if (count == 1) // Only support one file dropped { if (IsFileExtension(droppedFiles[0], ".obj") || IsFileExtension(droppedFiles[0], ".gltf") || IsFileExtension(droppedFiles[0], ".iqm")) // Model file formats supported { UnloadModel(model); // Unload previous model model = LoadModel(droppedFiles[0]); // Load new model // Set current map diffuse texture Utils.SetMaterialTexture(ref model, 0, MAP_ALBEDO, ref texture); meshes = (Mesh *)model.meshes.ToPointer(); bounds = MeshBoundingBox(meshes[0]); // TODO: Move camera position from target enough distance to visualize model properly } else if (IsFileExtension(droppedFiles[0], ".png")) // Texture file formats supported { // Unload current model texture and load new one UnloadTexture(texture); texture = LoadTexture(droppedFiles[0]); Utils.SetMaterialTexture(ref model, 0, MAP_ALBEDO, ref texture); } } ClearDroppedFiles(); // Clear internal buffers } // Select model on mouse click if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { // Check collision between ray and box if (CheckCollisionRayBox(GetMouseRay(GetMousePosition(), camera), bounds)) { selected = !selected; } else { selected = false; } } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); BeginMode3D(camera); DrawModel(model, position, 1.0f, WHITE); // Draw 3d model with texture DrawGrid(20, 10.0f); // Draw a grid if (selected) { DrawBoundingBox(bounds, GREEN); // Draw selection box } EndMode3D(); DrawText("Drag & drop model to load mesh/texture.", 10, GetScreenHeight() - 20, 10, DARKGRAY); if (selected) { DrawText("MODEL SELECTED", GetScreenWidth() - 110, 10, 10, GREEN); } DrawText("(c) Castle 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- UnloadTexture(texture); // Unload texture UnloadModel(model); // Unload model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return(0); }
public static void Unload(string path) { if (pixelBuffers == null) { pixelBuffers = new Dictionary <string, PixelBuffer>(); } if (scripts == null) { scripts = new Dictionary <string, ObjectInstance>(); } if (audio == null) { audio = new Dictionary <string, Sound>(); } if (music == null) { music = new Dictionary <string, Music>(); } if (texts == null) { texts = new Dictionary <string, string>(); } if (models == null) { models = new Dictionary <string, Model>(); } if (pixelBuffers.ContainsKey(path)) { pixelBuffers.Remove(path); } if (scripts.ContainsKey(path)) { scripts.Remove(path); } if (audio.ContainsKey(path)) { audio.Remove(path); } if (music.ContainsKey(path)) { music.Remove(path); } if (texts.ContainsKey(path)) { texts.Remove(path); } if (shaders.ContainsKey(path)) { Raylib.UnloadShader(shaders[path]); shaders.Remove(path); } if (models.ContainsKey(path)) { unsafe { Mesh *meshes = (Mesh *)models[path].meshes.ToPointer(); Raylib.UnloadMesh(ref meshes[0]); } models.Remove(path); } GC.Collect(); }