diff --git a/ActionParams.json b/ActionParams.json new file mode 100644 index 0000000..0383349 --- /dev/null +++ b/ActionParams.json @@ -0,0 +1,193 @@ +[ + { + "type": 1, + "availableParams": { + "duration": "Float", + "webUrl": "String", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 2, + "availableParams": { + "duration": "Float", + "translation": "VectorArray", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 3, + "availableParams": { + "duration": "Float", + "rotation": "VectorArray", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 4, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 5, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 6, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 7, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 8, + "availableParams": { + "duration": "Float", + "speed": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 9, + "availableParams": { + "duration": "Float", + "startFrame": "Float", + "endFrame": "Float", + "fps": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 10, + "availableParams": { + "duration": "Float", + "repeatCount": "Int", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 11, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 12, + "availableParams": { + "duration": "Float", + "scale": "VectorArray", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 13, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 14, + "availableParams": { + "duration": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 15, + "availableParams": { + "duration": "Float", + "alpha": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 16, + "availableParams": { + "duration": "Float", + "alpha": "Float", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 17, + "availableParams": { + "squareMoveWidth": "Float", + "squareMoveHeight": "Float", + "squareMoveTime": "Float", + "squareMoveRotationTime": "Float", + "clockwise": "Boolean", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 18, + "availableParams": { + "duration": "Float", + "roundMoveRadius": "Float", + "roundMoveStartAngle": "Float", + "roundMoveEndAngel": "Float", + "resolution": "Float", + "clockwise": "Boolean", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 19, + "availableParams": { + "duration": "Float", + "moveToFaceDistance": "Float", + "isAutoReturn": "Boolean", + "autoReturnDelay": "Float", + "isFaceToMe": "Boolean", + "targetID": "Int", + "groupNumber": "Int" + } + }, + { + "type": 20, + "availableParams": { + "duration": "Float", + "webUrl": "String", + "groupNumber": "Int" + } + }, + { + "type": 21, + "availableParams": { + "vibrationTime": "Float", + "groupNumber": "Int" + } + }, +] \ No newline at end of file diff --git a/ArModelData.json b/ArModelData.json new file mode 100644 index 0000000..a2aa8be --- /dev/null +++ b/ArModelData.json @@ -0,0 +1,491 @@ +[ + { + "id": 0, + "name": "Plane", + "position": { + "x": 0, + "y": -1, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "type": 0, + "material": { + "contentType": "image/jpeg", + "id": "d6350683.jpg", + "textureUrl": "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + }, + "params": { + "width": 1, + "height": 0.815, + "isSizeScaleLock": true + } + }, + "events": [ + { + "actions": [ + { + "actionType": 2, + "alpha": 1, + "autoReturnDelay": 3, + "clockwise": true, + "duration": 1, + "endFrame": 100, + "fps": 24, + "groupNumber": 0, + "isAutoReturn": true, + "isFaceToMe": true, + "moveToFaceDistance": 1, + "repeatCount": 1, + "resolution": 16, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "roundMoveEndAngel": 360, + "roundMoveRadius": 1, + "roundMoveStartAngle": 0, + "scale": { + "x": 0, + "y": 0, + "z": 0 + }, + "speed": 1, + "squareMoveHeight": 1, + "squareMoveRotationTime": 0.8, + "squareMoveTime": 1, + "squareMoveWidth": 1, + "startFrame": 0, + "targetId": 0, + "translation": { + "x": 1, + "y": 0, + "z": 0 + }, + "vibrationTime": 1, + "webUrl": "" + } + ], + "eventType": 1 + } + ] + }, + { + "id": 1, + "name": "Cube", + "position": { + "x": 1, + "y": -1, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "image/jpeg", + "id": "d6350683.jpg", + "textureUrl": "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + }, + "params": { + "width": 0.75, + "height": 0.75, + "depth": 0.75 + }, + "type": 1 + } + }, + { + "id": 2, + "name": "Sphere", + "position": { + "x": 2, + "y": -1, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "type": 2, + "material": { + "contentType": "image/jpeg", + "id": "d6350683.jpg", + "textureUrl": "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + }, + "params": { + "availableRange": 20, + "isDoubleSided": true, + "isFaceMe": false, + "isHidden": false, + "isIgnore": false, + "isOcclusion": false, + "radius": 0.45 + } + } + }, + { + "id": 3, + "name": "Cylinder", + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "image/jpeg", + "id": "d6350683.jpg", + "textureUrl": "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + }, + "params": { + "availableRange": 20, + "height": 1, + "isDoubleSided": true, + "isFaceMe": false, + "isHidden": false, + "isIgnore": false, + "isOcclusion": false, + "radius": 0.25 + }, + "type": 3 + } + }, + { + "id": 4, + "name": "Model3D", + "position": { + "x": 1, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "model/gltf-binary", + "id": "spiderbot.glb", + "textureUrl": "https://www.ray650128.com/spiderbot.glb" + }, + "params": { + "availableRange": 20, + "isDoubleSided": true, + "isFaceMe": false, + "isHidden": false, + "isIgnore": false, + "isMultiplyPlane": false, + "isOcclusion": false, + "modelEndFrame": 100, + "modelFPS": 24, + "modelStartFrame": 0, + "multiplyNumber": 10, + "multiplyRadius": 1, + "multiplyRange": 1 + }, + "type": 4 + } + }, + { + "id": 5, + "name": "Video1", + "position": { + "x": 1, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "video/mpeg4", + "id": "ker1.mp4", + "textureUrl": "https://www.ray650128.com/video/ker1.mp4" + }, + "params": { + "availableRange": 20, + "hueAngle": 120, + "hueRange": 20, + "isDoubleSided": true, + "isFaceMe": false, + "isHidden": false, + "isIgnore": false, + "isOcclusion": false, + "isPlayWhenReady": true, + "isRepeat": true, + "saturation": 80, + "videoThumbnail": "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + }, + "type": 5 + } + }, + { + "id": 6, + "name": "Video2", + "position": { + "x": 2, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "video/mpeg4", + "id": "ker2.mp4", + "textureUrl": "https://www.ray650128.com/video/ker2.mp4" + }, + "params": { + "availableRange": 20, + "hueAngle": 124, + "hueRange": 20, + "isDoubleSided": true, + "isFaceMe": false, + "isHidden": false, + "isIgnore": false, + "isOcclusion": false, + "saturation": 80 + }, + "type": 5 + } + }, + { + "id": 7, + "name": "Video3", + "position": { + "x": 3, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "video/mpeg4", + "id": "hou1.mp4", + "textureUrl": "https://www.ray650128.com/video/hou1.mp4" + }, + "params": { + "availableRange": 20, + "hueAngle": 35, + "hueRange": 20, + "isDoubleSided": true, + "isFaceMe": false, + "isHidden": false, + "isIgnore": false, + "isOcclusion": false, + "saturation": 50 + }, + "type": 5 + } + }, + { + "id": 8, + "name": "Light", + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "params": { + "availableRange": 20, + "color": { + "r": 1, + "g": 1, + "b": 0, + "a": 0 + }, + "lightIntensity": 25000 + }, + "type": 100 + } + }, + { + "id": 9, + "name": "MultiFace", + "position": { + "x": 0, + "y": 1, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentTypes": [ + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg", + "image/jpeg" + ], + "textureUrls": [ + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + ] + }, + "params": { + "levelAngles": [ + 45, + 0, + -45 + ], + "levelBorders": [ + 0.1, + 0.1, + 0.1 + ], + "levelCount": 3, + "planeBorder": 0.1, + "planeCount": 5, + "speed": 1 + }, + "type": 6 + } + }, + { + "id": 10, + "name": "Sign", + "position": { + "x": 1, + "y": 1, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "scale": { + "x": 1, + "y": 1, + "z": 1 + }, + "modelData": { + "material": { + "contentType": "image/jpeg", + "id": "d6350683.jpg", + "textureUrl": "https://cdn2.ettoday.net/images/6350/d6350683.jpg" + }, + "params": { + "availableRange": 20, + "signIcon": "https://cdn2.ettoday.net/images/6350/d6350683.jpg", + "signName": "0.0/", + "signTextColor": { + "r": 1, + "g": 0, + "b": 0, + "a": 0 + } + }, + "type": 7 + } + } +] \ No newline at end of file diff --git a/ModelParams.json b/ModelParams.json new file mode 100644 index 0000000..207266b --- /dev/null +++ b/ModelParams.json @@ -0,0 +1,151 @@ +[ + { + "type": 0, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "width": "Float", + "height": "Float", + "isSizeScaleLock": "Float" + } + }, + { + "type": 1, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "width": "Float", + "height": "Float", + "depth": "Float" + } + }, + { + "type": 2, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "radius": "Float" + } + }, + { + "type": 3, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "radius": "Float", + "height": "Float" + } + }, + { + "type": 4, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "modelAnimSpeed": "Float", + "modelStartFrame": "Float", + "modelEndFrame": "Float", + "modelFPS": "Float", + "multiplyNumber": "Int", + "multiplyRadius": "Float", + "multiplyRange": "Float", + "isMultiplyPlane": "Boolean" + } + }, + { + "type": 5, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "hueAngle": "Float", + "hueRange": "Float", + "saturation": "Float", + "isPlayWhenReady": "Boolean", + "isRepeat": "Boolean", + "videoThumbnail": "String" + } + }, + { + "type": 6, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "levelCount": "Int", + "levelBorders": "FloatArray", + "levelAngles": "FloatArray", + "planeCount": "Int", + "planeBorder": "Boolean", + "speed": "Float", + "isClockwise": "Boolean" + } + }, + { + "type": 7, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "width": "Float", + "height": "Float", + "signIcon": "String", + "signName": "String", + "signTextColor": "ColorArray" + } + }, + { + "type": 100, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "lightIntensity": "Float", + "color": "ColorArray" + } + }, + { + "type": 101, + "availableParams": { + "isFaceMe": "Boolean", + "isIgnore": "Boolean", + "isHidden": "Boolean", + "isDoubleSided": "Boolean", + "isOcclusion": "Boolean", + "availableRange": "Float", + "lightIntensity": "Float", + "color": "ColorArray" + } + } +] \ No newline at end of file diff --git a/NewArModelData.json b/NewArModelData.json new file mode 100644 index 0000000..0ab374c --- /dev/null +++ b/NewArModelData.json @@ -0,0 +1,131 @@ +{ + "id": 0, + "name": "TEST", + "type": 0, + "location": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "rotation": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "scale": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "params": { + "width": 0.0, + "height": 0.0, + "depth": 0.0, + "radius": 0.0, + "isSizeScaleLock": false, + "availableRange": 20.0, + "isFaceMe": false, + "isIgnore": false, + "isHidden": false, + "isDoubleSided": false, + "isOcclusion": false, + "modelAnimSpeed": 0.0, + "modelStartFrame": 0, + "modelEndFrame": 0, + "modelFPS": 0.0, + "multiplyNumber": 0, + "multiplyRadius": 0.0, + "multiplyRange": 0.0, + "isMultiplyPlane": false, + "hueAngle": 0.0, + "hueRange": 0.0, + "saturation": 0.0, + "isPlayWhenReady": false, + "isRepeat": true, + "videoThumbnail": "", + "levelCount": 3, + "levelBorders": [0.5, 0.5, 0.5], + "levelAngles": [30.0, 0.0, -30.0], + "planeCount": 5, + "planeBorder": 0.25, + "speed": 60, + "isClockwise": true, + "signIcon": { + "textureId": 0, + "fileName": "", + "materialUrl": "", + "contentType": "image/png" + }, + "signName": "", + "signTextColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "lightIntensity": 1000.0, + "color": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + } + }, + "material": [ + { + "textureId": 0, + "fileName": "", + "materialUrl": "", + "contentType": "image/png" + } + ], + "events": [ + { + "eventType": 1, + "actions": [ + { + "actionType": 2, + "alpha": 1, + "autoReturnDelay": 3, + "clockwise": true, + "duration": 1, + "endFrame": 100, + "fps": 24, + "groupNumber": 0, + "isAutoReturn": true, + "isFaceToMe": true, + "moveToFaceDistance": 1, + "repeatCount": 1, + "resolution": 16, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "roundMoveEndAngel": 360, + "roundMoveRadius": 1, + "roundMoveStartAngle": 0, + "scale": { + "x": 0, + "y": 0, + "z": 0 + }, + "speed": 1, + "squareMoveHeight": 1, + "squareMoveRotationTime": 0.8, + "squareMoveTime": 1, + "squareMoveWidth": 1, + "startFrame": 0, + "targetId": 0, + "translation": { + "x": 1, + "y": 0, + "z": 0 + }, + "vibrationTime": 1, + "webUrl": "" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/Application.kt b/src/main/kotlin/com/ray650128/Application.kt index 53b7ac7..2ef9b76 100644 --- a/src/main/kotlin/com/ray650128/Application.kt +++ b/src/main/kotlin/com/ray650128/Application.kt @@ -3,6 +3,7 @@ package com.ray650128 import com.ray650128.model.pojo.User import com.ray650128.plugins.configureUserRouting import com.ray650128.plugins.configureArMaterialRouting +import com.ray650128.plugins.configureArModelRouting import com.ray650128.service.UserService import io.ktor.serialization.kotlinx.json.* import io.ktor.server.application.* @@ -38,5 +39,6 @@ fun main() { } configureUserRouting() configureArMaterialRouting() + configureArModelRouting() }.start(wait = true) } diff --git a/src/main/kotlin/com/ray650128/extension/ArModelExtension.kt b/src/main/kotlin/com/ray650128/extension/ArModelExtension.kt new file mode 100644 index 0000000..eeeb8e8 --- /dev/null +++ b/src/main/kotlin/com/ray650128/extension/ArModelExtension.kt @@ -0,0 +1,32 @@ +package com.ray650128.extension + +import com.ray650128.model.pojo.arModel.ArModel +import com.ray650128.model.pojo.arModelDto.ArModelDto + +fun ArModel.toDto(): ArModelDto = + ArModelDto( + _id = this._id.toString(), + ownerId = this.ownerId.toString(), + name = this.name, + position = this.position, + rotation = this.rotation, + scale = this.scale, + modelData = this.modelData.toDto(), + events = this.events, + childEvents = this.childEvents, + createAt = this.createAt, + updatedAt = this.updatedAt + ) + +fun ArModelDto.toArModel(): ArModel = + ArModel( + name = this.name, + position = this.position, + rotation = this.rotation, + scale = this.scale, + modelData = this.modelData.toModelData(), + events = this.events, + childEvents = this.childEvents, + createAt = this.createAt, + updatedAt = this.updatedAt + ) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/extension/ModelDataExtension.kt b/src/main/kotlin/com/ray650128/extension/ModelDataExtension.kt new file mode 100644 index 0000000..92d5200 --- /dev/null +++ b/src/main/kotlin/com/ray650128/extension/ModelDataExtension.kt @@ -0,0 +1,22 @@ +package com.ray650128.extension + +import com.ray650128.model.pojo.arModel.ModelData +import com.ray650128.model.pojo.arModelDto.ModelDataDto +import com.ray650128.service.MaterialService + +fun ModelData.toDto(): ModelDataDto { + val service = MaterialService() + return ModelDataDto( + type = this.type, + material = service.findById(this.material.toString()), + params = this.params + ) +} + + +fun ModelDataDto.toModelData(): ModelData = + ModelData( + type = this.type, + material = this.material?._id, + params = this.params + ) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/ArModel.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/ArModel.kt new file mode 100644 index 0000000..50083ad --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/ArModel.kt @@ -0,0 +1,22 @@ +package com.ray650128.model.pojo.arModel + +import com.ray650128.model.pojo.User +import kotlinx.serialization.Contextual +import kotlinx.serialization.Serializable +import org.litote.kmongo.Id +import org.litote.kmongo.newId + +@Serializable +data class ArModel( + @Contextual var _id: Id? = newId(), + @Contextual var ownerId: Id? = null, + var name: String, + var position: Float3, + var rotation: Float3, + var scale: Float3, + var modelData: ModelData, + var events: ArrayList? = null, + var childEvents: HashMap?>? = null, + var createAt: Long? = null, + var updatedAt: Long? = null +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/Color.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/Color.kt new file mode 100644 index 0000000..7440e7b --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/Color.kt @@ -0,0 +1,11 @@ +package com.ray650128.model.pojo.arModel + +import kotlinx.serialization.Serializable + +@Serializable +data class Color( + var r: Float = 0.0f, + var g: Float = 0.0f, + var b: Float = 0.0f, + var a: Float = 0.0f +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/Float3.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/Float3.kt new file mode 100644 index 0000000..1daa8e3 --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/Float3.kt @@ -0,0 +1,10 @@ +package com.ray650128.model.pojo.arModel + +import kotlinx.serialization.Serializable + +@Serializable +data class Float3( + var x: Float, + var y: Float, + var z: Float +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelAction.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelAction.kt new file mode 100644 index 0000000..8885886 --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelAction.kt @@ -0,0 +1,44 @@ +package com.ray650128.model.pojo.arModel + +import kotlinx.serialization.Serializable + +@Serializable +data class ModelAction( + var actionType: Int, + var duration: Float?, + var translation: Float3? = null, + var rotation: Float3? = null, + var scale: Float3? = null, + var alpha: Float? = null, + + var webUrl: String? = null, + + var speed: Float? = null, + var startFrame: Float? = null, + var endFrame: Float? = null, + var fps: Float? = null, + + var repeatCount: Int? = null, + + var squareMoveWidth: Float? = null, + var squareMoveHeight: Float? = null, + var squareMoveTime: Float? = null, + var squareMoveRotationTime: Float? = null, + + var clockwise: Boolean? = null, + + var roundMoveRadius: Float? = null, + var roundMoveStartAngle: Float? = null, + var roundMoveEndAngel: Float? = null, + var resolution: Float? = null, + + var moveToFaceDistance: Float? = null, + var isAutoReturn: Boolean? = null, + var autoReturnDelay: Float? = null, + var isFaceToMe: Boolean? = null, + + var vibrationTime: Int? = null, + + var targetId: Int? = null, + var groupNumber: Int? = null +) diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelData.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelData.kt new file mode 100644 index 0000000..ed7c99a --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelData.kt @@ -0,0 +1,13 @@ +package com.ray650128.model.pojo.arModel + +import com.ray650128.model.pojo.Material +import kotlinx.serialization.Contextual +import kotlinx.serialization.Serializable +import org.litote.kmongo.Id + +@Serializable +data class ModelData( + var type: Int = -1, + @Contextual var material: Id? = null, + var params: ModelParams +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelEvent.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelEvent.kt new file mode 100644 index 0000000..62874b7 --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelEvent.kt @@ -0,0 +1,9 @@ +package com.ray650128.model.pojo.arModel + +import kotlinx.serialization.Serializable + +@Serializable +data class ModelEvent( + var eventType: Int, + var actions: ArrayList? = null +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelParams.kt b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelParams.kt new file mode 100644 index 0000000..1509dff --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModel/ModelParams.kt @@ -0,0 +1,51 @@ +package com.ray650128.model.pojo.arModel + +import kotlinx.serialization.Serializable + +@Serializable +data class ModelParams( + var isFaceMe: Boolean = false, + var isIgnore: Boolean = false, + var isHidden: Boolean = false, + var isDoubleSided: Boolean = true, + var isOcclusion: Boolean = false, + var availableRange: Float = 20f, + + var width: Float? = null, + var height: Float? = null, + var depth: Float? = null, + var radius: Float? = null, + var isSizeScaleLock: Boolean? = null, + + var modelAnimSpeed: Float? = null, + var modelStartFrame: Float? = null, + var modelEndFrame: Float? = null, + var modelFPS: Float? = null, + + var multiplyNumber: Int? = null, + var multiplyRadius: Float? = null, + var multiplyRange: Float? = null, + var isMultiplyPlane: Boolean? = null, + + var hueAngle: Float? = null, + var hueRange: Float? = null, + var saturation: Float? = null, + var isPlayWhenReady: Boolean? = null, + var isRepeat: Boolean? = null, + var videoThumbnail: String? = null, + + var lightIntensity: Float? = null, + var color: Color? = null, + + var levelCount: Int? = null, + var levelBorders: ArrayList? = null, + var levelAngles: ArrayList? = null, + var planeCount: Int? = null, + var planeBorder: Float? = null, + var speed: Float? = null, + var isClockwise: Boolean? = null, + + var signIcon: String? = null, + var signName: String? = null, + var signTextColor: Color? = null +) diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModelDto/ArModelDto.kt b/src/main/kotlin/com/ray650128/model/pojo/arModelDto/ArModelDto.kt new file mode 100644 index 0000000..9b8698e --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModelDto/ArModelDto.kt @@ -0,0 +1,20 @@ +package com.ray650128.model.pojo.arModelDto + +import com.ray650128.model.pojo.arModel.Float3 +import com.ray650128.model.pojo.arModel.ModelEvent +import kotlinx.serialization.Serializable + +@Serializable +data class ArModelDto( + var _id: String? = null, + var ownerId: String? = null, + var name: String, + var position: Float3, + var rotation: Float3, + var scale: Float3, + var modelData: ModelDataDto, + var events: ArrayList? = null, + var childEvents: HashMap?>? = null, + var createAt: Long? = null, + var updatedAt: Long? = null +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/model/pojo/arModelDto/ModelDataDto.kt b/src/main/kotlin/com/ray650128/model/pojo/arModelDto/ModelDataDto.kt new file mode 100644 index 0000000..cb4873c --- /dev/null +++ b/src/main/kotlin/com/ray650128/model/pojo/arModelDto/ModelDataDto.kt @@ -0,0 +1,14 @@ +package com.ray650128.model.pojo.arModelDto + +import com.ray650128.model.pojo.Material +import com.ray650128.model.pojo.arModel.ModelParams +import kotlinx.serialization.Contextual +import kotlinx.serialization.Serializable +import org.litote.kmongo.Id + +@Serializable +data class ModelDataDto( + var type: Int = -1, + var material: Material? = null, + var params: ModelParams +) \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/plugins/ArModelRouting.kt b/src/main/kotlin/com/ray650128/plugins/ArModelRouting.kt new file mode 100644 index 0000000..1837d37 --- /dev/null +++ b/src/main/kotlin/com/ray650128/plugins/ArModelRouting.kt @@ -0,0 +1,89 @@ +package com.ray650128.plugins + +import com.ray650128.extension.* +import com.ray650128.model.ErrorResponse +import com.ray650128.model.pojo.arModel.ArModel +import com.ray650128.model.pojo.User +import com.ray650128.service.ModelService +import com.ray650128.service.UserService +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.request.* +import io.ktor.server.routing.* + +fun Application.configureArModelRouting() { + + val userService = UserService() + val modelService = ModelService() + + routing { + route("/api") { + route("/v1") { + authenticate { + route("/models") { + get { + val account = call.authentication.principal()?.account ?: run { + call.sendUnauthorized() + return@get + } + val user = userService.findByAccount(account) ?: run { + call.sendUnauthorized() + return@get + } + val list = modelService.findByOwnerId(user._id.toString()).map(ArModel::toDto) + call.sendSuccess(list) + } + + post("/create") { + val user = call.authentication.principal() ?: run { + call.sendUnauthorized() + return@post + } + val body = call.receive() + body.apply { + ownerId = user._id + createAt = System.currentTimeMillis() + } + val modelId = modelService.create(body) + if (modelId != null) { + val data = modelService.findById(modelId.toString())?.toDto() + call.sendSuccess(data) + } else { + call.sendBadRequest(ErrorResponse("Add ar model fail.")) + } + } + + put("/{id}") { + call.authentication.principal()?.account ?: run { + call.sendUnauthorized() + return@put + } + val body = call.receive() + val id = call.parameters["id"].toString() + val model = modelService.findById(id) ?: run { + call.sendNotFound() + return@put + } + body.apply { + ownerId = model.ownerId + createAt = model.createAt + } + val isSuccess = modelService.updateById(id, body) + call.sendSuccess(mapOf("success" to isSuccess)) + } + + delete("/{id}") { + call.authentication.principal()?.account ?: run { + call.sendUnauthorized() + return@delete + } + val id = call.parameters["id"].toString() + val isSuccess = modelService.deleteById(id) + call.sendSuccess(mapOf("success" to isSuccess)) + } + } + } + } + } + } +} diff --git a/src/main/kotlin/com/ray650128/service/ModelService.kt b/src/main/kotlin/com/ray650128/service/ModelService.kt new file mode 100644 index 0000000..65b9f4e --- /dev/null +++ b/src/main/kotlin/com/ray650128/service/ModelService.kt @@ -0,0 +1,51 @@ +package com.ray650128.service + +import com.ray650128.model.pojo.arModel.ArModel +import com.ray650128.model.pojo.User +import org.bson.types.ObjectId +import org.litote.kmongo.* +import org.litote.kmongo.id.toId + +class ModelService { + private val client = KMongo.createClient("mongodb://www.ray650128.com:27017") + private val database = client.getDatabase("ar_system") + private val arModelCollection = database.getCollection() + + fun create(arModel: ArModel): Id? { + arModelCollection.insertOne(arModel) + return arModel._id + } + + fun findAll(): List = arModelCollection.find().toList() + + fun findById(id: String): ArModel? { + val bsonId: Id = ObjectId(id).toId() + return arModelCollection.findOne(ArModel::_id eq bsonId) + } + + fun findByOwnerId(ownerId: String): List { + val bsonId: Id = ObjectId(ownerId).toId() + return arModelCollection.find(ArModel::ownerId eq bsonId).toList() + } + + fun findByName(name: String): List { + val caseSensitiveTypeSafeFilter = ArModel::name regex name + return arModelCollection.find(caseSensitiveTypeSafeFilter).toList() + } + + fun updateById(id: String, request: ArModel): Boolean = + findById(id)?.let { arModel -> + val updateResult = arModelCollection.replaceOne( + arModel.copy( + name = request.name, + updatedAt = request.updatedAt + ) + ) + updateResult.modifiedCount == 1L + } ?: false + + fun deleteById(id: String): Boolean { + val deleteResult = arModelCollection.deleteOneById(ObjectId(id)) + return deleteResult.deletedCount == 1L + } +} \ No newline at end of file