OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
pfxemittermesh.cpp
Go to the documentation of this file.
1#include "pfxemittermesh.h"
2
6
7#include <Tempest/Log>
8
10 vertices.resize(src.vertices.size());
11 for(size_t i=0;i<vertices.size();++i) {
12 vertices[i].x = src.vertices[i].pos[0];
13 vertices[i].y = src.vertices[i].pos[1];
14 vertices[i].z = src.vertices[i].pos[2];
15 }
16 for(size_t i=0;i<src.indices.size();i+=3) {
17 Triangle t;
18 t.id[0] = src.indices[i+0];
19 t.id[1] = src.indices[i+1];
20 t.id[2] = src.indices[i+2];
21 triangle.push_back(t);
22 }
23
24 mkIndex();
25 }
26
27PfxEmitterMesh::PfxEmitterMesh(const zenkit::ModelMesh& library) {
28 for(const auto &i : library.meshes) {
30
31 size_t vert0 = vertices.size();
32 vertAnim.resize(vert0 + src.vertices.size());
33 for(size_t i=0;i<src.vertices.size();++i) {
34 auto& v = src.vertices[i];
35 for(size_t r=0; r<4; ++r) {
36 vertAnim[vert0+i].v[r].x = v.LocalPositions[r].x;
37 vertAnim[vert0+i].v[r].y = v.LocalPositions[r].y;
38 vertAnim[vert0+i].v[r].z = v.LocalPositions[r].z;
39
40 vertAnim[vert0+i].id[r] = v.BoneIndices[r];
41 vertAnim[vert0+i].weights[r] = v.Weights[r];
42 }
43 }
44
45 for(size_t i=0;i<src.indices.size();i+=3) {
46 Triangle t;
47 t.id[0] = src.indices[i+0];
48 t.id[1] = src.indices[i+1];
49 t.id[2] = src.indices[i+2];
50 triangle.push_back(t);
51 }
52 }
53
54 mkIndex();
55}
56
57Tempest::Vec3 PfxEmitterMesh::randCoord(float rnd, const Pose* pose) const {
58 if(triangle.size()==0)
59 return Tempest::Vec3();
60
61 rnd*=triangle.back().prefix;
62
63 auto it = std::lower_bound(triangle.begin(),triangle.end(),rnd,[](const Triangle& t,float v){
64 return t.prefix<v;
65 });
66 if(it!=triangle.begin())
67 it--;
68 return randCoord(*it,rnd,pose);
69 }
70
71Tempest::Vec3 PfxEmitterMesh::randCoord(const PfxEmitterMesh::Triangle& t, float rnd,
72 const Pose* pose) const {
73 rnd = (rnd-t.prefix)/t.sz;
74
75 float det = float(std::numeric_limits<uint16_t>::max());
76 uint32_t k = uint32_t(rnd*float(std::numeric_limits<uint32_t>::max()));
77
78 float r1 = float((k>>16)&0xFFFF)/det;
79 float r2 = float((k )&0xFFFF)/det;
80
81 float sr1 = std::sqrt(r1);
82
83 if(vertices.size()>0) {
84 auto& a = vertices[t.id[0]];
85 auto& b = vertices[t.id[1]];
86 auto& c = vertices[t.id[2]];
87 return a*(1.f-sr1) + b*(sr1*(1-r2)) + c*(r2*sr1);
88 } else {
89 auto a = animCoord(*pose,t.id[0]);
90 auto b = animCoord(*pose,t.id[1]);
91 auto c = animCoord(*pose,t.id[2]);
92
93 return a*(1.f-sr1) + b*(sr1*(1-r2)) + c*(r2*sr1);
94 }
95 }
96
97Tempest::Vec3 PfxEmitterMesh::animCoord(const Pose& pose, uint32_t id) const {
98 Tempest::Vec3 ret = {};
99 auto& v = vertAnim[id];
100 for(size_t i=0; i<4; ++i) {
101 auto& mat = pose.bone(v.id[i]);
102 Tempest::Vec3 a = v.v[i];
103 mat.project(a);
104 ret += a*v.weights[i];
105 }
106 return ret;//*0.1f;
107 }
108
109float PfxEmitterMesh::area(float x1, float y1, float z1,
110 float x2, float y2, float z2,
111 float x3, float y3, float z3) {
112 x1 -= x3;
113 y1 -= y3;
114 z1 -= z3;
115
116 x2 -= x3;
117 y2 -= y3;
118 z2 -= z3;
119
120 float x = y1*z2 - z1*y2;
121 float y = z1*x2 - x1*z2;
122 float z = x1*y2 - y1*x2;
123
124 return std::sqrt(x*x + y*y + z*z); //note: omnit 0.5
125 }
126
127void PfxEmitterMesh::mkIndex() {
128 if(vertices.size()>0) {
129 for(auto& t:triangle) {
130 auto& a = vertices[t.id[0]];
131 auto& b = vertices[t.id[1]];
132 auto& c = vertices[t.id[2]];
133
134 t.sz = area(a.x,a.y,a.z, b.x,b.y,b.z, c.x,c.y,c.z);
135 }
136 } else {
137 for(auto& t:triangle) {
138 auto& a = vertAnim[t.id[0]].v[0];
139 auto& b = vertAnim[t.id[1]].v[0];
140 auto& c = vertAnim[t.id[2]].v[0];
141
142 t.sz = area(a.x,a.y,a.z, b.x,b.y,b.z, c.x,c.y,c.z);
143 }
144 }
145
146 for(size_t i=1;i<triangle.size();++i) {
147 triangle[i].prefix += triangle[i-1].sz;
148 triangle[i].prefix += triangle[i-1].prefix;
149 }
150 }
std::vector< uint32_t > indices
Definition packedmesh.h:70
std::vector< Vertex > vertices
Definition packedmesh.h:68
Tempest::Vec3 randCoord(float rnd, const Pose *pose) const
PfxEmitterMesh(const PackedMesh &src)
Definition pose.h:16
auto bone(size_t id) const -> const Tempest::Matrix4x4 &
Definition pose.cpp:804
PackedSkeletalMesh pack_softskin_mesh(const zenkit::SoftSkinMesh &)
Definition phoenix.cpp:36