Spring Boot AR/VR API Sinhala Guide | AR/VR යෙදුම් සඳහා Backend
ආයුබෝවන් යාලුවනේ! කොහොමද හැමෝටම? තාක්ෂණික ලෝකයේ අලුත්ම trends ගැන උනන්දුවෙන් ඉන්න ඔයාලට අද මම අරගෙන ආවේ Augmented Reality (AR) සහ Virtual Reality (VR) යෙදුම් සඳහා Backend Service එකක් හදන හැටි ගැන ඉතා වැදගත් tutorial එකක්. අද කාලේ AR/VR කියන්නේ ගොඩක් දියුණු වෙමින් තියෙන ක්ෂේත්රයක්නේ. මේවා game වලට විතරක් නෙවෙයි, education, healthcare, retail වගේ ගොඩක් industries වලටත් දැන් යොදාගන්නවා.
හැබැයි මේ AR/VR apps හදද්දී ගොඩක් වෙලාවට අපිට දත්ත ගබඩා කරන්න (store data), අලුත් දත්ත එකතු කරන්න (add new data), පරිශීලකයන් කිහිප දෙනෙක්ට එකට වැඩ කරන්න පුළුවන් කරන්න (multi-user experiences), වගේ දේවල් වලට Backend Service එකක් ඕන වෙනවා. අන්න ඒ වගේ තැනකදී අපිට Spring Boot කියන Java Framework එක හොඳම විසඳුමක්. Spring Boot කියන්නේ robust, scalable, සහ develop කරන්න පහසු RESTful APIs හදන්න තියෙන සුපිරි platform එකක්.
මේ tutorial එකෙන් අපි බලමු:
- AR/VR යෙදුම් වලට Backend එකක් ඕන වෙන්නේ ඇයි කියලා.
- Spring Boot Project එකක් මුල ඉඳන් පටන් ගන්න හැටි.
- AR Objects වලට දත්ත සේවය කරන්න පුළුවන් සරල REST API එකක් හදන හැටි.
- Unity වැනි AR/VR client application එකකට මේ API එක integrate කරගන්න පුළුවන් කොහොමද කියලා (ඒ ගැන පොඩි හිතුවිල්ලක් විතරයි).
එහෙනම්, අපි පටන් ගමුද? Let's dive in!
AR/VR යෙදුම් සඳහා Backend එකක් ඕන ඇයි?
AR/VR යෙදුම් කියන්නේ නිකන්ම ත්රිමාන graphics විතරක් නෙවෙයි. ගොඩක් වෙලාවට මේවාට dynamic data, user interactions, සහ persistent state ඕන වෙනවා. ඒ කියන්නේ, game එකක් වගේ දෙයක් නම්, game එකේ level එක, player ගේ score එක, inventory එක වගේ දේවල් save වෙලා තියෙන්න ඕන. එහෙම නැත්නම්, AR training app එකක් නම්, training modules, user progress, scores වගේ දේවල් save වෙලා තියෙන්න ඕන. මේ වගේ scenarios වලදී, client-side application (Unity, Unreal Engine වගේ) එකට විතරක් ඔක්කොම data handle කරන්න බැහැ.
Backend එකක් අපිට මේ වගේ දේවල් වලට උදව් කරනවා:
- දත්ත ගබඩා කිරීම (Data Persistence): AR/VR ලෝකයේ ඔබ තබන virtual object එකක්, හෝ game එකක player ගේ state එක, app එක වහලා ආයෙත් open කරනකොටත් තියෙන්න ඕනේ නම්, ඒ දත්ත database එකක ගබඩා කරන්න Backend එකක් ඕන.
- Multi-User අත්දැකීම් (Multi-User Experiences): යාළුවෝ කිහිප දෙනෙක්ට එකම AR space එකක් share කරගන්න ඕනේ නම්, ඒ හැමෝටම එකම virtual object ටික පේන්න, ඒ අයගේ interactions share කරගන්න, Backend එකක් අත්යවශ්යයි.
- ගතික අන්තර්ගතය (Dynamic Content): අලුත් ත්රිමාන Models, textures, animations වගේ දේවල් app එකට add කරන්න හෝ update කරන්න ඕනේ නම්, ඒවා app එකට download කරන්න පුළුවන් විදියට Backend එකකින් සේවය කරන්න පුළුවන්.
- User Authentication සහ Authorization: Users ලාට login වෙන්න, ඔවුන්ගේ profile එක manage කරන්න, සහ ඇතැම් features වලට access control කරන්න Backend එකක් අවශ්යයි.
- ව්යාපාරික තර්කනය (Business Logic): සංකීර්ණ ගණනය කිරීම්, game rules වැනි දේවල් client-side එකට බර නොකර Backend එකකින් handle කරන්න පුළුවන්.
මේ වගේ දේවල් වලට තමයි අපි Spring Boot වගේ robust Backend Framework එකක් භාවිතා කරන්නේ.
Spring Boot Project එකක් පටන් ගමු
අපි දැන් Spring Boot Project එකක් හදාගමු. මේක හදන්න පහසුම ක්රමය තමයි Spring Initializr භාවිතා කරන එක.
පහත පියවර අනුගමනය කරන්න:
- Web Browser එකකින් https://start.spring.io/ open කරන්න.
- Project: 'Maven Project' තෝරන්න (Gradle භාවිතා කරනවා නම් ඒක තෝරාගන්න පුළුවන්).
- Language: 'Java' තෝරන්න.
- Spring Boot: අලුත්ම stable version එක තෝරන්න (උදා: 3.2.x).
- Project Metadata:
- Group:
com.example(ඔබේ company/organization name එකක් දෙන්න පුළුවන්) - Artifact:
ar-vr-backend(Project එකට කැමති නමක් දෙන්න) - Name:
ar-vr-backend - Description:
Demo project for AR/VR backend - Package name:
com.example.arvrbackend - Packaging:
Jar - Java:
17හෝ21(ඔබේ Java SDK version එකට ගැලපෙන එක)
- Group:
- Dependencies: 'Add Dependencies' button එක click කරලා පහත ඒවා add කරන්න:
Spring Web: අපේ REST APIs හදන්න මේක අත්යවශ්යයි.Lombok(Optional but Recommended): Boilerplate code (Getters, Setters, Constructors) අඩු කරන්න උදව් වෙනවා.
- අවසානයේ 'Generate' button එක click කරන්න.
ඔබට ar-vr-backend.zip කියලා file එකක් download වෙයි. මේක unzip කරලා ඔබේ කැමති IDE (IntelliJ IDEA, VS Code, Eclipse) එකකින් open කරගන්න.
ඔබගේ pom.xml file එකේ <dependencies> කොටස මේ වගේ වෙන්න ඕන (versions වෙනස් වෙන්න පුළුවන්):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
ඔබගේ Project එකේ src/main/java/com/example/arvrbackend/ArVrBackendApplication.java file එක මේ වගේ වෙයි:
package com.example.arvrbackend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ArVrBackendApplication {
public static void main(String[] args) {
SpringApplication.run(ArVrBackendApplication.class, args);
}
}
දැන් Project එක හරි. අපි දැන් AR Object data serve කරන්න පුළුවන් API එකක් හදමු.
AR Object Data API එකක් හදමු
AR/VR ලෝකයේ 'object' එකක් කියන්නේ මොකක්ද? ඒක 3D model එකක් වෙන්න පුළුවන්, light source එකක් වෙන්න පුළුවන්, හෝ virtual interaction point එකක් වෙන්න පුළුවන්. මේ tutorial එකට අපි සරලව හිතමු, අපේ AR object එකකට id එකක්, name එකක්, position (x,y,z coordinates), rotation (x,y,z angles), scale (x,y,z factors), සහ modelUrl එකක් (ඒකේ 3D model එක download කරන්න පුළුවන් URL එකක්) තියෙනවා කියලා.
මුලින්ම අපි මේ AR Object එකට Java Class එකක් හදාගමු. src/main/java/com/example/arvrbackend/model කියන package එකක් හදලා ඒක ඇතුලේ ARObject.java කියලා file එකක් හදන්න.
package com.example.arvrbackend.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// Lombok annotations for boilerplate code
@Data // Generates getters, setters, toString, equals, hashCode
@NoArgsConstructor // Generates a constructor with no arguments
@AllArgsConstructor // Generates a constructor with all arguments
public class ARObject {
private String id;
private String name;
private float positionX;
private float positionY;
private float positionZ;
private float rotationX;
private float rotationY;
private float rotationZ;
private float scaleX;
private float scaleY;
private float scaleZ;
private String modelUrl; // URL to download the 3D model (e.g., .glb, .obj, .fbx)
private String description;
// You can add more properties as needed, e.g., textureUrl, material properties, interactions
}
දැන් අපි මේ AR Objects manage කරන්න REST Controller එකක් හදමු. src/main/java/com/example/arvrbackend/controller කියන package එකක් හදලා ඒක ඇතුලේ ARObjectController.java කියලා file එකක් හදන්න.
සරලව තේරුම් ගන්න අපි database එකක් භාවිතා කරන්නේ නැතුව, List<ARObject> එකක් මතකයේ තියාගෙන වැඩ කරමු. (Real world apps වලට database එකක් භාවිතා කරන්න වෙනවා, ඒ ගැන අපි පස්සේ කතා කරමු.)
package com.example.arvrbackend.controller;
import com.example.arvrbackend.model.ARObject;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@RestController // Marks this class as a Spring REST Controller
@RequestMapping("/api/arobjects") // Base path for all endpoints in this controller
public class ARObjectController {
// In-memory list to simulate a database for demonstration purposes
private List<ARObject> arObjects = new ArrayList<>();
// Initialize with some dummy data
public ARObjectController() {
arObjects.add(new ARObject(
UUID.randomUUID().toString(),
"Cube", 0f, 0f, 0f, 0f, 0f, 0f, 1f, 1f, 1f,
"http://example.com/models/cube.glb",
"A basic red cube"
));
arObjects.add(new ARObject(
UUID.randomUUID().toString(),
"Sphere", 1f, 1f, 1f, 0f, 0f, 0f, 0.5f, 0.5f, 0.5f,
"http://example.com/models/sphere.glb",
"A floating blue sphere"
));
}
// Endpoint to get all AR Objects
// GET http://localhost:8080/api/arobjects
@GetMapping
public List<ARObject> getAllArObjects() {
System.out.println("Fetching all AR objects");
return arObjects;
}
// Endpoint to get a specific AR Object by ID
// GET http://localhost:8080/api/arobjects/{id}
@GetMapping("/{id}")
public Optional<ARObject> getArObjectById(@PathVariable String id) {
System.out.println("Fetching AR object with ID: " + id);
return arObjects.stream().filter(obj -> obj.getId().equals(id)).findFirst();
}
// Endpoint to create a new AR Object
// POST http://localhost:8080/api/arobjects
// Request Body: JSON representation of ARObject (without ID)
@PostMapping
public ARObject createArObject(@RequestBody ARObject arObject) {
arObject.setId(UUID.randomUUID().toString()); // Assign a unique ID
arObjects.add(arObject);
System.out.println("Created new AR object: " + arObject.getName());
return arObject;
}
// Endpoint to update an existing AR Object
// PUT http://localhost:8080/api/arobjects/{id}
// Request Body: JSON representation of ARObject (with updated fields)
@PutMapping("/{id}")
public Optional<ARObject> updateArObject(@PathVariable String id, @RequestBody ARObject updatedArObject) {
Optional<ARObject> existingArObject = arObjects.stream().filter(obj -> obj.getId().equals(id)).findFirst();
if (existingArObject.isPresent()) {
ARObject obj = existingArObject.get();
obj.setName(updatedArObject.getName());
obj.setPositionX(updatedArObject.getPositionX());
obj.setPositionY(updatedArObject.getPositionY());
obj.setPositionZ(updatedArObject.getPositionZ());
obj.setRotationX(updatedArObject.getRotationX());
obj.setRotationY(updatedArObject.getRotationY());
obj.setRotationZ(updatedArObject.getRotationZ());
obj.setScaleX(updatedArObject.getScaleX());
obj.setScaleY(updatedArObject.getScaleY());
obj.setScaleZ(updatedArObject.getScaleZ());
obj.setModelUrl(updatedArObject.getModelUrl());
obj.setDescription(updatedArObject.getDescription());
System.out.println("Updated AR object with ID: " + id);
return Optional.of(obj);
}
System.out.println("AR object not found for ID: " + id);
return Optional.empty(); // Object not found
}
// Endpoint to delete an AR Object
// DELETE http://localhost:8080/api/arobjects/{id}
@DeleteMapping("/{id}")
public boolean deleteArObject(@PathVariable String id) {
boolean removed = arObjects.removeIf(obj -> obj.getId().equals(id));
if (removed) {
System.out.println("Deleted AR object with ID: " + id);
} else {
System.out.println("AR object not found for deletion with ID: " + id);
}
return removed;
}
}
දැන් ඔබට ඔබේ Spring Boot Application එක Run කරන්න පුළුවන්. ඔබේ IDE එකේ ArVrBackendApplication.java එකේ main method එක Run කරන්න. නැත්නම් command line එකේ mvn spring-boot:run කියලා type කරන්න.
Application එක start වුණාට පස්සේ, ඔබට Postman, Insomnia, හෝ ඔබේ web browser එකෙන් මේ API endpoints test කරන්න පුළුවන්:
- සියලු AR Objects ලබා ගැනීමට:
GET http://localhost:8080/api/arobjects
අලුත් AR Object එකක් එකතු කිරීමට (POST request):
URL: http://localhost:8080/api/arobjects
Headers: Content-Type: application/json
Body (Raw JSON):
{
"name": "Tree",
"positionX": 2.0,
"positionY": 0.0,
"positionZ": -3.0,
"rotationX": 0.0,
"rotationY": 45.0,
"rotationZ": 0.0,
"scaleX": 1.5,
"scaleY": 1.5,
"scaleZ": 1.5,
"modelUrl": "http://example.com/models/tree.glb",
"description": "A lush green tree"
}මේ විදියට ඔබට AR/VR client application එකකට අවශ්ය දත්ත සපයන්න පුළුවන් සරල Backend එකක් සාදාගන්න පුළුවන්.
Unity සමග ඒකාබද්ධ කිරීම ගැන පොඩි හිතුවිල්ලක්
අපි මේ හදපු API එක AR/VR client application එකකට, උදාහරණයක් විදියට Unity Engine එකට, integrate කරගන්නේ කොහොමද? ගොඩක්ම සරලයි!
Unity වලට HTTP requests කරන්න පුළුවන් UnityWebRequest කියන class එක තියෙනවා. මේක භාවිතා කරලා අපි හදපු Spring Boot API එකට requests යවලා, data ගන්න, යවන්න, update කරන්න, delete කරන්න පුළුවන්. Response එක JSON format එකෙන් තමයි එන්නේ. Unity වලට JSON data parse කරන්නත් පහසු methods තියෙනවා (JsonUtility). ඒ වගේම Newtonsoft.Json වගේ third-party librariesත් භාවිතා කරන්න පුළුවන්.
පහත දැක්වෙන්නේ Unity (C#) script එකක් ඇතුළත අපේ API එකෙන් AR Objects ගන්න පුළුවන් විදිය ගැන සරල සංකල්පයක්:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;
// A simple class to mirror our ARObject Java class
[System.Serializable]
public class ARObjectData
{
public string id;
public string name;
public float positionX, positionY, positionZ;
public float rotationX, rotationY, rotationZ;
public float scaleX, scaleY, scaleZ;
public string modelUrl;
public string description;
}
// A helper class to deserialize a list of ARObjects
[System.Serializable]
public class ARObjectList
{
public ARObjectData[] arObjects;
}
public class ArApiConsumer : MonoBehaviour
{
private const string API_BASE_URL = "http://localhost:8080/api/arobjects";
void Start()
{
StartCoroutine(GetArObjects());
}
IEnumerator GetArObjects()
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(API_BASE_URL))
{
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError("Error: " + webRequest.error);
}
else
{
Debug.Log("Received: " + webRequest.downloadHandler.text);
// Parse the JSON response
// For a list, you might need a wrapper class or deserialize manually
// ARObjectData[] objects = JsonUtility.FromJson<ARObjectData[]>("{\"arObjects\":" + webRequest.downloadHandler.text + "}").arObjects;
// For simplicity, let's assume we get a single object or handle list parsing manually
// Example of parsing a list (requires a wrapper object if using JsonUtility)
// A simple way to parse a list if the root is an array:
// string jsonArray = webRequest.downloadHandler.text;
// List<ARObjectData> arObjectList = JsonConvert.DeserializeObject<List<ARObjectData>>(jsonArray); // Requires Newtonsoft.Json
// Or manually parse with a wrapper for JsonUtility:
string jsonWrapper = "{\"arObjects\":" + webRequest.downloadHandler.text + "}";
ARObjectList receivedList = JsonUtility.FromJson<ARObjectList>(jsonWrapper);
if (receivedList != null && receivedList.arObjects != null)
{
foreach (ARObjectData arObject in receivedList.arObjects)
{
Debug.Log($"AR Object Name: {arObject.name}, Position: ({arObject.positionX}, {arObject.positionY}, {arObject.positionZ})");
// Here you would instantiate 3D models in your Unity scene
// based on arObject.modelUrl, position, rotation, scale etc.
}
}
else
{
Debug.LogWarning("No AR objects found or parsing failed.");
}
}
}
}
// Example for POST request
IEnumerator PostArObject(ARObjectData newObject)
{
string jsonBody = JsonUtility.ToJson(newObject);
using (UnityWebRequest webRequest = UnityWebRequest.Post(API_BASE_URL, "POST"))
{
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonBody);
webRequest.uploadHandler = new UploadHandlerRaw(bodyRaw);
webRequest.downloadHandler = new DownloadHandlerBuffer();
webRequest.SetRequestHeader("Content-Type", "application/json");
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError("Error: " + webRequest.error);
}
else
{
Debug.Log("Object Created: " + webRequest.downloadHandler.text);
}
}
}
}
(සටහන: Unity වලට JsonUtility.FromJson භාවිතා කරලා array එකක් කෙලින්ම parse කරන්න පොඩි සීමාවක් තියෙනවා, ඒක නිසා අපි ARObjectList wrapper class එකක් භාවිතා කළා. Newtonsoft.Json වගේ external library එකක් භාවිතා කරනවා නම් මේක තව පහසුයි.)
මේ ArApiConsumer script එක Unity GameObject එකකට attach කරලා, Run කළාම, අපේ Spring Boot Backend එකෙන් data අරගෙන console එකේ print කරනවා දකින්න පුළුවන්.
තව දුරටත් සලකා බැලීම්:
- Real-time Updates: AR/VR වලට ගොඩක් වෙලාවට real-time updates ඕන වෙනවා (උදා: එක් පරිශීලකයෙක් virtual object එකක් move කරනකොට අනිත් අයටත් ඒක ක්ෂණිකව පේන්න). මේවාට WebSockets භාවිතා කරන්න පුළුවන්. Spring Boot වලට Spring WebSocket support එක තියෙනවා.
- Scalability: පරිශීලකයන් වැඩි වන විට Backend එකේ ධාරිතාව (capacity) වැඩි කරන්න Cloud platforms (AWS, Azure, GCP) වල microservices architecture එකක්, containerization (Docker, Kubernetes) වැනි දේවල් යොදාගන්න පුළුවන්.
- Authentication/Authorization: Spring Security භාවිතා කරලා API එක ආරක්ෂා කරන්න පුළුවන්.
අවසන් වශයෙන්
අද අපි Spring Boot භාවිතයෙන් AR/VR යෙදුම් සඳහා Backend API එකක් හදන ආකාරය ගැන සවිස්තරාත්මකව කතා කළා. AR/VR apps වලට Backend එකක අවශ්යතාවය, Spring Boot Project එකක් ආරම්භ කරන ආකාරය, AR Object දත්ත කළමනාකරණය කරන RESTful API එකක් ගොඩනගන ආකාරය, සහ එය Unity වැනි client එකක් සමඟ ඒකාබද්ධ කරගැනීම ගැන අපි සාකච්ඡා කළා. මේ සරල උදාහරණය ඔබේ AR/VR Project වලට Backend Services එකතු කරන්න හොඳ ආරම්භයක් වේවි කියලා මම හිතනවා.
දැන් ඔයාලට පුළුවන් මේක තව දුරටත් දියුණු කරන්න. Database (MySQL, PostgreSQL) එකක් එකතු කරලා data persistent කරන්න, User Authentication add කරන්න, WebSockets වලින් real-time functionality එකතු කරන්න වගේ දේවල් කරන්න පුළුවන්. මේ වගේ දේවල් කරලා බලන එකෙන් තමයි ඔයාගේ දැනුම වැඩි වෙන්නේ.
මේ tutorial එකෙන් ඔයාලට අලුත් දෙයක් ඉගෙන ගන්න ලැබුණා නම්, අනිවාර්යයෙන්ම comment section එකේ ඔබේ අදහස්, ප්රශ්න, හෝ අත්දැකීම් බෙදාගන්න. ඔයාලත් මේක හදලා බලන්න, ඒක තමයි වැදගත්ම දේ. අපේ තාක්ෂණික ගමනට එකතු වෙන්න! ජය වේවා!