1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <cmath> 19 #include <memory> 20 #include <vector> 21 22 #include "TextureAsset.h" 23 24 union Vector3 { 25 struct { 26 float x, y, z; 27 }; 28 float idx[3]; 29 Vector3 operator*(float value) { return Vector3{{x * value, y * value, z * value}}; } 30 Vector3 operator/(float value) { return Vector3{{x / value, y / value, z / value}}; } 31 Vector3 operator+(Vector3 const &other) { 32 return Vector3{{x + other.x, y + other.y, z + other.z}}; 33 } 34 Vector3 operator-(Vector3 const &other) { 35 return Vector3{{x - other.x, y - other.y, z - other.z}}; 36 } 37 }; 38 39 union Vector2 { 40 struct { 41 float x, y; 42 }; 43 struct { 44 float u, v; 45 }; 46 float idx[2]; 47 }; 48 49 struct Vertex { VertexVertex50 constexpr Vertex(const Vector3 &inPosition, const Vector2 &inUV) 51 : position(inPosition), uv(inUV) {} 52 53 Vector3 position; 54 Vector2 uv; 55 }; 56 57 typedef uint16_t Index; 58 59 class Model { 60 public: Model(std::vector<Vertex> vertices,std::vector<Index> indices,std::shared_ptr<TextureAsset> spTexture)61 inline Model(std::vector<Vertex> vertices, std::vector<Index> indices, 62 std::shared_ptr<TextureAsset> spTexture) 63 : currentVertices_(vertices), 64 startVertices_(std::move(vertices)), 65 indices_(std::move(indices)), 66 spTexture_(std::move(spTexture)) { 67 findCenter(); 68 } 69 getVertexData()70 inline const Vertex *getVertexData() const { return currentVertices_.data(); } 71 getIndexCount()72 inline size_t getIndexCount() const { return indices_.size(); } 73 getIndexData()74 inline const Index *getIndexData() const { return indices_.data(); } 75 getTexture()76 inline const TextureAsset &getTexture() const { return *spTexture_; } 77 getCenter()78 inline const Vector3 getCenter() { return center_; } 79 move(Vector3 offset)80 void move(Vector3 offset) { 81 for (int i = 0; i < startVertices_.size(); ++i) { 82 startVertices_[i].position = startVertices_[i].position + offset; 83 currentVertices_[i].position = currentVertices_[i].position + offset; 84 } 85 center_ = center_ + offset; 86 } 87 setRotation(float angle)88 void setRotation(float angle) { 89 float rad = angle + rotationOffset_; 90 for (int i = 0; i < startVertices_.size(); ++i) { 91 Vector3 normalized = startVertices_[i].position - center_; 92 Vector3 out{{0, 0, 0}}; 93 out.x = normalized.x * cos(rad) - normalized.y * sin(rad); 94 out.y = normalized.x * sin(rad) + normalized.y * cos(rad); 95 currentVertices_[i].position = out + center_; 96 } 97 } 98 setRotationOffset(float angle)99 void setRotationOffset(float angle) { rotationOffset_ = angle; } 100 101 private: findCenter()102 void findCenter() { 103 Vector3 center{{0, 0, 0}}; 104 for (auto &&vertex : startVertices_) { 105 center = center + vertex.position; 106 } 107 center_ = center / static_cast<float>(startVertices_.size()); 108 } 109 110 Vector3 center_; 111 std::vector<Vertex> currentVertices_; 112 std::vector<Vertex> startVertices_; 113 std::vector<Index> indices_; 114 std::shared_ptr<TextureAsset> spTexture_; 115 float rotationOffset_; 116 }; 117