{"id":21023201,"url":"https://github.com/simerplaha/slack3d","last_synced_at":"2025-05-15T08:32:52.105Z","repository":{"id":57722830,"uuid":"415955431","full_name":"simerplaha/Slack3D","owner":"simerplaha","description":"Simple 3D graphics library","archived":false,"fork":false,"pushed_at":"2023-05-08T12:54:19.000Z","size":7600,"stargazers_count":30,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-03T06:41:55.029Z","etag":null,"topics":["3d","graphics","linear-algebra","scala"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simerplaha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["simerplaha"]}},"created_at":"2021-10-11T14:11:52.000Z","updated_at":"2024-12-28T05:52:20.000Z","dependencies_parsed_at":"2022-09-26T21:50:13.164Z","dependency_job_id":null,"html_url":"https://github.com/simerplaha/Slack3D","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2FSlack3D","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2FSlack3D/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2FSlack3D/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simerplaha%2FSlack3D/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simerplaha","download_url":"https://codeload.github.com/simerplaha/Slack3D/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254304645,"owners_count":22048446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d","graphics","linear-algebra","scala"],"created_at":"2024-11-19T11:17:12.007Z","updated_at":"2025-05-15T08:32:47.090Z","avatar_url":"https://github.com/simerplaha.png","language":"Scala","funding_links":["https://github.com/sponsors/simerplaha"],"categories":[],"sub_categories":[],"readme":"# Slack3D [![Maven central][maven-badge]][maven-link]\n\n[gitter-badge]: https://badges.gitter.im/Join%20Chat.svg\n\n[gitter-link]: https://gitter.im/Slack3D/community\n\n[maven-badge]: https://img.shields.io/maven-central/v/com.github.simerplaha/slack3d_2.13.svg\n\n[maven-link]: https://search.maven.org/search?q=g:com.github.simerplaha%20AND%20a:slack3d_2.13\n\nSimple 3D graphics engine.\n\n![Bunny.gif](docs/bunny.gif)\n\n# Features\n\n- Phong lighting\n- Fly style camera - Freely move around a 3D scene\n- Text rendering - English characters and numbers.\n- Out of the box Shapes - Vector, Box, Circle, Cone, Cylinder, HeightField, Plane, Point, Pyramid, Sphere, Tetrahedron,\n  Triangle, Line \u0026 Ray\n- OpenGL via LWJGL3\n- User input to transform and rotate shapes.\n- Basic linear algebra library - `Matrix3`, `Matrix2`, `Vector3` \u0026 `Vector2`\n- Immutable API\n\n## Key controls\n\n- W, A, S, D - Move along all 3 axes\n- Mouse drag - Changes camera view position\n- Enter - Return to initial camera view\n- Space (Hold!) - Pauses rendering/animation (camera is still active) \n\n## Setup\n\n```scala\nlibraryDependencies += \"com.github.simerplaha\" %% \"slack3d\" % \"0.1.0\"\n```\n\n### LWJGL VM Option\n\nAllow LWJGL to run on main thread with `-XstartOnFirstThread` in VM options. If you are using IntelliJ set the flag in\nthe \"Build and run\" window.\n\n![img.png](docs/intellij_vm_option.png)\n\n## Rendering\n\nSlack3D can be thought of a collection instance where your code provide shapes to render for each frame.\n\nRender a sphere of radius `0.5` of colour `Purple`.\n\n```scala\nSlack3D(\"A sphere\") foreach {\n  state =\u003e //State of current render\n    //shapes to render\n    Seq(Sphere(radius = 0.5, colour = Colour.Purple))\n}\n```\n\n![img.png](docs/purple_sphere.png)\n\n## Interval rendering\n\nRender shapes after some time interval. The following will render a `Sphere` of radius `0.5` with a new colour after\nevery 1.second.\n\n```scala\nSlack3D(\"Colour\").foreach(interval = 1.second) {\n  _ =\u003e\n    Seq(Sphere(0.5, colour = Colour.next()))\n}\n```\n\n![colour_changing_sphere.gif](docs/colour_changing_sphere.gif)\n\nAll OpenGL colours can be found class type [Colour](/graphics/src/main/scala/slack3d/graphics/colour/Colour.scala). To\nget the next colour from a randomly sorted colour queue use```Colour.next()```\n\n## Rotation\n\nApply Y axis rotation to the box.\n\n```scala\nSlack3D(\"Rotating Box\") foreach {\n  state =\u003e\n    //same code as above but with added rotation at Y axis\n    val box = Box(Colour.Red).rotateY(state.getTime() * 30)\n    Seq(box)\n}\n```\n\n![Cube_rotate.gif](docs/cube_rotate.gif)\n\nRotation can be applied to all axis. See APIs\n\n![rotation_api.png](docs/rotation_api.png)\n\n## Rotation with user inputs\n\nConfigures the `Box` to be\n\n- **translatable** when `Z` key is pressed and arrows keys are moved\n- **rotatable** when `X` key is pressed and arrows keys are moved\n\n```scala\nSlack3D(\"Custom rotation\").foldLeft(Box()) {\n  case (_box, state) =\u003e\n    val box =\n      _box\n        .translatable(state.window, GLFW.GLFW_KEY_Z) //translate box when Z key is pressed\n        .rotatable(state.window, GLFW.GLFW_KEY_X) //rotate box when X key is pressed\n\n    (box, Seq(box))\n}\n```\n\n![custom_rotate.gif.png](docs/custom_rotate.gif)\n\n## Lines/Vectors\n\nCreate 2 vectors where the third vector is a cross product.\n\n```scala\nSlack3D(\"Lines and vectors\") foreach {\n  state =\u003e\n    //vector1\n    val vector1 = Vector3(0.5, -0.5, 0)\n    //vector2\n    val vector2 = Vector3(0.5, 0.5, 0)\n    //cross product\n    val cross = vector1 cross vector2\n\n    Seq(\n      Line(vector1, Colour.Red),\n      Line(vector2, Colour.Yellow),\n      Line(cross, Colour.Green)\n    )\n}\n```\n\n![cross_product_vectors.png](docs/cross_product_vectors.png)\n\nAll `Lines` and `Points` will render a text displaying the position and length of that vector.\n\n## Configurations\n\nYou can change the width, height, title, camera etc. See the following example.\n\n```scala\nSlack3D(\n  title = \"My configurations\", //window title\n  width = 800, //window width\n  height = 600, //window height\n  backgroundColor = Colour.Orange,\n  enableWireframes = true, //configures OpenGL in wireframes mode. \n  camera = None, // disable camera or provide your custom instance. See how default works\n  enable2DCoordinates = false, //enables or disables coordinate drawing\n  perspective = None, //perspective view\n  light = None //configures lighting \n) foreach {\n  state =\u003e\n    //no shapes to render\n    Seq.empty\n}\n```\n\n## Custom shapes\n\nAll shapes are a combination of primitives `Triangle`, `Line` or a `Point`.\n\n```scala\n/**\n * A custom shape that render text and a line\n */\ncase class MyCustomShape(text: Text,\n                         line: Cylinder) extends Shape {\n\n  override type Self = MyCustomShape\n\n  //function to apply to each vector on this shape.\n  //this function is used for applying perspective, rotation \u0026 translation\n  override def map(f: Vector3[Double] =\u003e Vector3[Double]): MyCustomShape =\n    MyCustomShape(\n      text = text.map(f),\n      line = line.map(f)\n    )\n\n  //expands each shape into points, lines and triangles\n  override def buildMesh(mesh: Mesh[Point, LineOrRay, Triangle]): Unit = {\n    text buildMesh mesh\n    line buildMesh mesh\n  }\n}\n\n//Start Slack3D instance and render the above custom shape\nSlack3D(\"My custom shape\") foreach {\n  state =\u003e\n    //create my custom shape instance\n    val myShape =\n      MyCustomShape(\n        text = Text(\"My custom shape text\", Colour.White) * 2 + Vector3(-0.6, 0.4), //a scaled \u0026 translated custom text\n        line = Cylinder(Colour.Purple) / 2 //A scaled down cylinder\n      )\n\n    Seq(myShape)\n}\n```\n\n![custom_shape.png](docs/custom_shape.png)\n\n# Sponsors\n\nThank you Jetbrains for providing an open-source licence for their awesome development tools.\n\n\u003ca href=\"https://www.jetbrains.com/?from=Slack3D\" target=\"_blank\"\u003e\u003cimg src=\"/docs/jetbrains.png\" alt=\"Jetbrains support\" height=\"150\" border=\"10\" /\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimerplaha%2Fslack3d","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimerplaha%2Fslack3d","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimerplaha%2Fslack3d/lists"}