Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
BlockMesh.cs
浏览该文件的文档.
1using System.Runtime.InteropServices;
2using Engine;
4using Engine.Media;
5
6namespace Game {
7 public class BlockMesh {
8 public struct InternalVertex {
10
12
14 }
15
16 public DynamicArray<BlockMeshVertex> Vertices = [];
17
18 public DynamicArray<int> Indices = [];
19
20 public DynamicArray<sbyte> Sides;
21
22 public object m_tag;
23
24 public object Tag {
25 get => m_tag;
26 set => m_tag = value;
27 }
28
30 return new BoundingBox(Vertices.Select(v => v.Position));
31 }
32
33 public virtual BoundingBox CalculateBoundingBox(Matrix matrix) {
34 return new BoundingBox(Vertices.Select(v => Vector3.Transform(v.Position, matrix)));
35 }
36
37 public static Matrix GetBoneAbsoluteTransform(ModelBone modelBone) {
38 if (modelBone.ParentBone != null) {
39 return GetBoneAbsoluteTransform(modelBone.ParentBone) * modelBone.Transform;
40 }
41 return modelBone.Transform;
42 }
43
44 public virtual void AppendImageExtrusion(Image image, Rectangle bounds, Vector3 size, Color color) {
45 BlockMesh blockMesh = new();
46 DynamicArray<BlockMeshVertex> vertices = blockMesh.Vertices;
47 DynamicArray<int> indices = blockMesh.Indices;
48 BlockMeshVertex item = new() {
49 Position = new Vector3(bounds.Left, bounds.Top, -1f), TextureCoordinates = new Vector2(bounds.Left, bounds.Top)
50 };
51 vertices.Add(item);
52 item = new BlockMeshVertex {
53 Position = new Vector3(bounds.Right, bounds.Top, -1f), TextureCoordinates = new Vector2(bounds.Right, bounds.Top)
54 };
55 vertices.Add(item);
56 item = new BlockMeshVertex {
57 Position = new Vector3(bounds.Left, bounds.Bottom, -1f), TextureCoordinates = new Vector2(bounds.Left, bounds.Bottom)
58 };
59 vertices.Add(item);
60 item = new BlockMeshVertex {
61 Position = new Vector3(bounds.Right, bounds.Bottom, -1f), TextureCoordinates = new Vector2(bounds.Right, bounds.Bottom)
62 };
63 vertices.Add(item);
64 indices.Add(vertices.Count - 4);
65 indices.Add(vertices.Count - 1);
66 indices.Add(vertices.Count - 3);
67 indices.Add(vertices.Count - 1);
68 indices.Add(vertices.Count - 4);
69 indices.Add(vertices.Count - 2);
70 item = new BlockMeshVertex {
71 Position = new Vector3(bounds.Left, bounds.Top, 1f), TextureCoordinates = new Vector2(bounds.Left, bounds.Top)
72 };
73 vertices.Add(item);
74 item = new BlockMeshVertex {
75 Position = new Vector3(bounds.Right, bounds.Top, 1f), TextureCoordinates = new Vector2(bounds.Right, bounds.Top)
76 };
77 vertices.Add(item);
78 item = new BlockMeshVertex {
79 Position = new Vector3(bounds.Left, bounds.Bottom, 1f), TextureCoordinates = new Vector2(bounds.Left, bounds.Bottom)
80 };
81 vertices.Add(item);
82 item = new BlockMeshVertex {
83 Position = new Vector3(bounds.Right, bounds.Bottom, 1f), TextureCoordinates = new Vector2(bounds.Right, bounds.Bottom)
84 };
85 vertices.Add(item);
86 indices.Add(vertices.Count - 4);
87 indices.Add(vertices.Count - 3);
88 indices.Add(vertices.Count - 1);
89 indices.Add(vertices.Count - 1);
90 indices.Add(vertices.Count - 2);
91 indices.Add(vertices.Count - 4);
92 for (int i = bounds.Left - 1; i <= bounds.Right; i++) {
93 int num = -1;
94 for (int j = bounds.Top - 1; j <= bounds.Bottom; j++) {
95 bool num2 = !bounds.Contains(new Point2(i, j)) || image.GetPixelFast(i, j).IsCompletelyTransparent();
96 bool flag = bounds.Contains(new Point2(i - 1, j)) && !image.GetPixelFast(i - 1, j).IsCompletelyTransparent();
97 if (num2 & flag) {
98 if (num < 0) {
99 num = j;
100 }
101 }
102 else if (num >= 0) {
103 item = new BlockMeshVertex {
104 Position = new Vector3(i - 0.01f, num - 0.01f, -1.01f), TextureCoordinates = new Vector2(i - 1 + 0.01f, num + 0.01f)
105 };
106 vertices.Add(item);
107 item = new BlockMeshVertex {
108 Position = new Vector3(i - 0.01f, num - 0.01f, 1.01f), TextureCoordinates = new Vector2(i - 0.01f, num + 0.01f)
109 };
110 vertices.Add(item);
111 item = new BlockMeshVertex {
112 Position = new Vector3(i - 0.01f, j + 0.01f, -1.01f), TextureCoordinates = new Vector2(i - 1 + 0.01f, j - 0.01f)
113 };
114 vertices.Add(item);
115 item = new BlockMeshVertex {
116 Position = new Vector3(i - 0.01f, j + 0.01f, 1.01f), TextureCoordinates = new Vector2(i - 0.01f, j - 0.01f)
117 };
118 vertices.Add(item);
119 indices.Add(vertices.Count - 4);
120 indices.Add(vertices.Count - 1);
121 indices.Add(vertices.Count - 3);
122 indices.Add(vertices.Count - 1);
123 indices.Add(vertices.Count - 4);
124 indices.Add(vertices.Count - 2);
125 num = -1;
126 }
127 }
128 }
129 for (int k = bounds.Left - 1; k <= bounds.Right; k++) {
130 int num3 = -1;
131 for (int l = bounds.Top - 1; l <= bounds.Bottom; l++) {
132 bool num4 = !bounds.Contains(new Point2(k, l)) || image.GetPixelFast(k, l).IsCompletelyTransparent();
133 bool flag2 = bounds.Contains(new Point2(k + 1, l)) && !image.GetPixelFast(k + 1, l).IsCompletelyTransparent();
134 if (num4 & flag2) {
135 if (num3 < 0) {
136 num3 = l;
137 }
138 }
139 else if (num3 >= 0) {
140 item = new BlockMeshVertex {
141 Position = new Vector3(k + 1 + 0.01f, num3 - 0.01f, -1.01f), TextureCoordinates = new Vector2(k + 1 + 0.01f, num3 + 0.01f)
142 };
143 vertices.Add(item);
144 item = new BlockMeshVertex {
145 Position = new Vector3(k + 1 + 0.01f, num3 - 0.01f, 1.01f), TextureCoordinates = new Vector2(k + 2 - 0.01f, num3 + 0.01f)
146 };
147 vertices.Add(item);
148 item = new BlockMeshVertex {
149 Position = new Vector3(k + 1 + 0.01f, l + 0.01f, -1.01f), TextureCoordinates = new Vector2(k + 1 + 0.01f, l - 0.01f)
150 };
151 vertices.Add(item);
152 item = new BlockMeshVertex {
153 Position = new Vector3(k + 1 + 0.01f, l + 0.01f, 1.01f), TextureCoordinates = new Vector2(k + 2 - 0.01f, l - 0.01f)
154 };
155 vertices.Add(item);
156 indices.Add(vertices.Count - 4);
157 indices.Add(vertices.Count - 3);
158 indices.Add(vertices.Count - 1);
159 indices.Add(vertices.Count - 1);
160 indices.Add(vertices.Count - 2);
161 indices.Add(vertices.Count - 4);
162 num3 = -1;
163 }
164 }
165 }
166 for (int m = bounds.Top - 1; m <= bounds.Bottom; m++) {
167 int num5 = -1;
168 for (int n = bounds.Left - 1; n <= bounds.Right; n++) {
169 bool num6 = !bounds.Contains(new Point2(n, m)) || image.GetPixelFast(n, m).IsCompletelyTransparent();
170 bool flag3 = bounds.Contains(new Point2(n, m - 1)) && !image.GetPixelFast(n, m - 1).IsCompletelyTransparent();
171 if (num6 & flag3) {
172 if (num5 < 0) {
173 num5 = n;
174 }
175 }
176 else if (num5 >= 0) {
177 item = new BlockMeshVertex {
178 Position = new Vector3(num5 - 0.01f, m - 0.01f, -1.01f), TextureCoordinates = new Vector2(num5 + 0.01f, m - 1 + 0.01f)
179 };
180 vertices.Add(item);
181 item = new BlockMeshVertex {
182 Position = new Vector3(num5 - 0.01f, m - 0.01f, 1.01f), TextureCoordinates = new Vector2(num5 + 0.01f, m - 0.01f)
183 };
184 vertices.Add(item);
185 item = new BlockMeshVertex {
186 Position = new Vector3(n + 0.01f, m - 0.01f, -1.01f), TextureCoordinates = new Vector2(n - 0.01f, m - 1 + 0.01f)
187 };
188 vertices.Add(item);
189 item = new BlockMeshVertex {
190 Position = new Vector3(n + 0.01f, m - 0.01f, 1.01f), TextureCoordinates = new Vector2(n - 0.01f, m - 0.01f)
191 };
192 vertices.Add(item);
193 indices.Add(vertices.Count - 4);
194 indices.Add(vertices.Count - 3);
195 indices.Add(vertices.Count - 1);
196 indices.Add(vertices.Count - 1);
197 indices.Add(vertices.Count - 2);
198 indices.Add(vertices.Count - 4);
199 num5 = -1;
200 }
201 }
202 }
203 for (int num7 = bounds.Top - 1; num7 <= bounds.Bottom; num7++) {
204 int num8 = -1;
205 for (int num9 = bounds.Left - 1; num9 <= bounds.Right; num9++) {
206 bool num10 = !bounds.Contains(new Point2(num9, num7)) || image.GetPixelFast(num9, num7).IsCompletelyTransparent();
207 bool flag4 = bounds.Contains(new Point2(num9, num7 + 1)) && !image.GetPixelFast(num9, num7 + 1).IsCompletelyTransparent();
208 if (num10 & flag4) {
209 if (num8 < 0) {
210 num8 = num9;
211 }
212 }
213 else if (num8 >= 0) {
214 item = new BlockMeshVertex {
215 Position = new Vector3(num8 - 0.01f, num7 + 1 + 0.01f, -1.01f),
216 TextureCoordinates = new Vector2(num8 + 0.01f, num7 + 1 + 0.01f)
217 };
218 vertices.Add(item);
219 item = new BlockMeshVertex {
220 Position = new Vector3(num8 - 0.01f, num7 + 1 + 0.01f, 1.01f),
221 TextureCoordinates = new Vector2(num8 + 0.01f, num7 + 2 - 0.01f)
222 };
223 vertices.Add(item);
224 item = new BlockMeshVertex {
225 Position = new Vector3(num9 + 0.01f, num7 + 1 + 0.01f, -1.01f),
226 TextureCoordinates = new Vector2(num9 - 0.01f, num7 + 1 + 0.01f)
227 };
228 vertices.Add(item);
229 item = new BlockMeshVertex {
230 Position = new Vector3(num9 + 0.01f, num7 + 1 + 0.01f, 1.01f),
231 TextureCoordinates = new Vector2(num9 - 0.01f, num7 + 2 - 0.01f)
232 };
233 vertices.Add(item);
234 indices.Add(vertices.Count - 4);
235 indices.Add(vertices.Count - 1);
236 indices.Add(vertices.Count - 3);
237 indices.Add(vertices.Count - 1);
238 indices.Add(vertices.Count - 4);
239 indices.Add(vertices.Count - 2);
240 num8 = -1;
241 }
242 }
243 }
244 for (int num11 = 0; num11 < vertices.Count; num11++) {
245 vertices.Array[num11].Position.X -= bounds.Left + bounds.Width / 2f;
246 vertices.Array[num11].Position.Y = bounds.Bottom - vertices.Array[num11].Position.Y - bounds.Height / 2f;
247 vertices.Array[num11].Position.X *= size.X / bounds.Width;
248 vertices.Array[num11].Position.Y *= size.Y / bounds.Height;
249 vertices.Array[num11].Position.Z *= size.Z / 2f;
250 vertices.Array[num11].TextureCoordinates.X /= image.Width;
251 vertices.Array[num11].TextureCoordinates.Y /= image.Height;
252 vertices.Array[num11].Color = color;
253 }
254 AppendBlockMesh(blockMesh);
255 }
256
257 public virtual void AppendModelMeshPart(ModelMeshPart meshPart,
258 Matrix matrix,
259 bool makeEmissive,
260 bool flipWindingOrder,
261 bool doubleSided,
262 bool flipNormals,
263 Color color) {
264 bool skipVanilla = false;
266 "OnFirstPersonModelDrawing",
267 loader => {
268 loader.OnAppendModelMeshPart(
269 this,
270 meshPart,
271 matrix,
272 makeEmissive,
273 flipWindingOrder,
274 doubleSided,
275 flipNormals,
276 color,
277 out bool skip
278 );
279 skipVanilla |= skip;
280 return false;
281 }
282 );
283 if (skipVanilla) {
284 return;
285 }
286 VertexBuffer vertexBuffer = meshPart.VertexBuffer;
287 IndexBuffer indexBuffer = meshPart.IndexBuffer;
288 ReadOnlyList<VertexElement> vertexElements = vertexBuffer.VertexDeclaration.VertexElements;
289 if (vertexElements.Count != 3
290 || vertexElements[0].Offset != 0
291 || vertexElements[0].Semantic != VertexElementSemantic.Position.GetSemanticString()
292 || vertexElements[1].Offset != 12
293 || vertexElements[1].Semantic != VertexElementSemantic.Normal.GetSemanticString()
294 || vertexElements[2].Offset != 24
295 || vertexElements[2].Semantic != VertexElementSemantic.TextureCoordinate.GetSemanticString()) {
296 throw new InvalidOperationException("Wrong vertex format for a block mesh.");
297 }
298 InternalVertex[] vertexData = GetVertexData<InternalVertex>(vertexBuffer);
299 int[] indexData = GetIndexData<int>(indexBuffer);
300 Dictionary<int, int> dictionary = new();
301 for (int i = meshPart.StartIndex; i < meshPart.StartIndex + meshPart.IndicesCount; i++) {
302 int num = indexData[i];
303 if (!dictionary.ContainsKey(num)) {
304 dictionary.Add(num, Vertices.Count);
305 BlockMeshVertex item = default;
306 item.Position = Vector3.Transform(vertexData[num].Position, matrix);
307 item.TextureCoordinates = vertexData[num].TextureCoordinate;
308 Vector3 vector = Vector3.Normalize(
309 Vector3.TransformNormal(flipNormals ? -vertexData[num].Normal : vertexData[num].Normal, matrix)
310 );
311 if (makeEmissive) {
312 item.IsEmissive = true;
313 item.Color = color;
314 }
315 else {
316 item.Color = color * LightingManager.CalculateLighting(vector);
317 item.Color.A = color.A;
318 }
319 item.Face = (byte)CellFace.Vector3ToFace(vector);
320 Vertices.Add(item);
321 }
322 }
323 for (int j = 0; j < meshPart.IndicesCount / 3; j++) {
324 if (doubleSided) {
325 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j]]);
326 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 1]]);
327 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 2]]);
328 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j]]);
329 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 2]]);
330 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 1]]);
331 }
332 else if (flipWindingOrder) {
333 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j]]);
334 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 2]]);
335 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 1]]);
336 }
337 else {
338 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j]]);
339 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 1]]);
340 Indices.Add(dictionary[indexData[meshPart.StartIndex + 3 * j + 2]]);
341 }
342 }
343 Trim();
344 }
345
346 public virtual void AppendBlockMesh(BlockMesh blockMesh) {
347 bool skipVanilla = false;
349 "OnFirstPersonModelDrawing",
350 loader => {
351 loader.OnAppendModelMesh(this, blockMesh, out bool skip);
352 skipVanilla |= skip;
353 return false;
354 }
355 );
356 if (skipVanilla) {
357 return;
358 }
359 int count = Vertices.Count;
360 for (int i = 0; i < blockMesh.Vertices.Count; i++) {
361 Vertices.Add(blockMesh.Vertices.Array[i]);
362 }
363 for (int j = 0; j < blockMesh.Indices.Count; j++) {
364 Indices.Add(blockMesh.Indices.Array[j] + count);
365 }
366 Trim();
367 }
368
369 public virtual void BlendBlockMesh(BlockMesh blockMesh, float factor) {
370 if (blockMesh.Vertices.Count != Vertices.Count) {
371 throw new InvalidOperationException("Meshes do not match.");
372 }
373 for (int i = 0; i < Vertices.Count; i++) {
374 Vector3 position = Vertices.Array[i].Position;
375 Vector3 position2 = blockMesh.Vertices.Array[i].Position;
376 Vertices.Array[i].Position = Vector3.Lerp(position, position2, factor);
377 }
378 }
379
380 public virtual void TransformPositions(Matrix matrix, int facesMask = -1) {
381 for (int i = 0; i < Vertices.Count; i++) {
382 if (((1 << Vertices.Array[i].Face) & facesMask) != 0) {
383 Vertices.Array[i].Position = Vector3.Transform(Vertices.Array[i].Position, matrix);
384 }
385 }
386 }
387
388 public virtual void TransformTextureCoordinates(Matrix matrix, int facesMask = -1) {
389 for (int i = 0; i < Vertices.Count; i++) {
390 if (((1 << Vertices.Array[i].Face) & facesMask) != 0) {
391 Vertices.Array[i].TextureCoordinates = Vector2.Transform(Vertices.Array[i].TextureCoordinates, matrix);
392 }
393 }
394 }
395
396 public virtual void SetColor(Color color, int facesMask = -1) {
397 for (int i = 0; i < Vertices.Count; i++) {
398 if (((1 << Vertices.Array[i].Face) & facesMask) != 0) {
399 Vertices.Array[i].Color = color;
400 }
401 }
402 }
403
404 public virtual void ModulateColor(Color color, int facesMask = -1) {
405 for (int i = 0; i < Vertices.Count; i++) {
406 if (((1 << Vertices.Array[i].Face) & facesMask) != 0) {
407 Vertices.Array[i].Color *= color;
408 }
409 }
410 }
411
412 public virtual void GenerateSidesData() {
413 Sides = [];
414 Sides.Count = Indices.Count / 3;
415 for (int i = 0; i < Sides.Count; i++) {
416 int num = Indices.Array[3 * i];
417 int num2 = Indices.Array[3 * i + 1];
418 int num3 = Indices.Array[3 * i + 2];
419 Vector3 position = Vertices.Array[num].Position;
420 Vector3 position2 = Vertices.Array[num2].Position;
421 Vector3 position3 = Vertices.Array[num3].Position;
422 if (IsNear(position.Z, position2.Z, position3.Z, 1f)) {
423 Sides.Array[i] = 0;
424 }
425 else if (IsNear(position.X, position2.X, position3.X, 1f)) {
426 Sides.Array[i] = 1;
427 }
428 else if (IsNear(position.Z, position2.Z, position3.Z, 0f)) {
429 Sides.Array[i] = 2;
430 }
431 else if (IsNear(position.X, position2.X, position3.X, 0f)) {
432 Sides.Array[i] = 3;
433 }
434 else if (IsNear(position.Y, position2.Y, position3.Y, 1f)) {
435 Sides.Array[i] = 4;
436 }
437 else {
438 Sides.Array[i] = IsNear(position.Y, position2.Y, position3.Y, 0f) ? (sbyte)5 : (sbyte)-1;
439 }
440 }
441 }
442
443 public virtual void Trim() {
444 Vertices.Capacity = Vertices.Count;
445 Indices.Capacity = Indices.Count;
446 if (Sides != null) {
447 Sides.Capacity = Sides.Count;
448 }
449 }
450
451 public static T[] GetVertexData<T>(VertexBuffer vertexBuffer) where T : unmanaged {
452 if (vertexBuffer.Tag is not byte[] array) {
453 throw new InvalidOperationException("VertexBuffer does not contain source data in Tag.");
454 }
455 if (array.Length % Utilities.SizeOf<T>() != 0) {
456 throw new InvalidOperationException("VertexBuffer data size is not a whole multiply of target type size.");
457 }
458 T[] array2 = new T[array.Length / Utilities.SizeOf<T>()];
459 GCHandle gCHandle = GCHandle.Alloc(array2, GCHandleType.Pinned);
460 try {
461 Marshal.Copy(array, 0, gCHandle.AddrOfPinnedObject(), Utilities.SizeOf<T>() * array2.Length);
462 return array2;
463 }
464 finally {
465 gCHandle.Free();
466 }
467 }
468
469 public static T[] GetIndexData<T>(IndexBuffer indexBuffer) where T : unmanaged {
470 if (indexBuffer.Tag is not byte[] array) {
471 throw new InvalidOperationException("IndexBuffer does not contain source data in Tag.");
472 }
473 if (array.Length % Utilities.SizeOf<T>() != 0) {
474 throw new InvalidOperationException("IndexBuffer data size is not a whole multiply of target type size.");
475 }
476 T[] array2 = new T[array.Length / Utilities.SizeOf<T>()];
477 GCHandle gCHandle = GCHandle.Alloc(array2, GCHandleType.Pinned);
478 try {
479 Marshal.Copy(array, 0, gCHandle.AddrOfPinnedObject(), Utilities.SizeOf<T>() * array2.Length);
480 return array2;
481 }
482 finally {
483 gCHandle.Free();
484 }
485 }
486
487 public static bool IsNear(float v1, float v2, float v3, float t) {
488 if (v1 - t >= -0.001f
489 && v1 - t <= 0.001f
490 && v2 - t >= -0.001f
491 && v2 - t <= 0.001f
492 && v3 - t >= -0.001f) {
493 return v3 - t <= 0.001f;
494 }
495 return false;
496 }
497
498 public virtual void AppendImageExtrusion(Image image, Rectangle bounds, Vector3 scale, Color color, int alphaThreshold) {
499 int count = Vertices.Count;
501 image,
502 bounds,
503 new Vector3(1f, 0f, 0f),
504 new Vector3(0f, 1f, 0f),
505 new Vector3(0f, 0f, 1f),
506 new Vector3(0f, 0f, 0f),
507 color,
508 alphaThreshold
509 );
511 image,
512 bounds,
513 new Vector3(1f, 0f, 0f),
514 new Vector3(0f, 1f, 0f),
515 new Vector3(0f, 0f, -1f),
516 new Vector3(0f, 0f, 1f),
517 color,
518 alphaThreshold
519 );
520 for (int i = bounds.Left; i < bounds.Right; i++) {
521 Image image2 = new(1, bounds.Height);
522 for (int j = bounds.Top; j < bounds.Bottom; j++) {
523 if (i == bounds.Left
524 || image.GetPixelFast(i - 1, j).A <= alphaThreshold) {
525 image2.SetPixelFast(0, j - bounds.Top, image.GetPixelFast(i, j));
526 }
527 }
529 image2,
530 new Rectangle(0, 0, image2.Width, image2.Height),
531 new Vector3(0f, 0f, 1f),
532 new Vector3(0f, 1f, 0f),
533 new Vector3(1f, 0f, 0f),
534 new Vector3(i, bounds.Top, 0f),
535 color,
536 alphaThreshold
537 );
538 }
539 for (int k = bounds.Left; k < bounds.Right; k++) {
540 Image image3 = new(1, bounds.Height);
541 for (int l = bounds.Top; l < bounds.Bottom; l++) {
542 if (k == bounds.Right - 1
543 || image.GetPixelFast(k + 1, l).A <= alphaThreshold) {
544 image3.SetPixelFast(0, l - bounds.Top, image.GetPixelFast(k, l));
545 }
546 }
548 image3,
549 new Rectangle(0, 0, image3.Width, image3.Height),
550 new Vector3(0f, 0f, 1f),
551 new Vector3(0f, 1f, 0f),
552 new Vector3(-1f, 0f, 0f),
553 new Vector3(k + 1, bounds.Top, 0f),
554 color,
555 alphaThreshold
556 );
557 }
558 for (int m = bounds.Top; m < bounds.Bottom; m++) {
559 Image image4 = new(bounds.Width, 1);
560 for (int n = bounds.Left; n < bounds.Right; n++) {
561 if (m == bounds.Top
562 || image.GetPixelFast(n, m - 1).A <= alphaThreshold) {
563 image4.SetPixelFast(n - bounds.Left, 0, image.GetPixelFast(n, m));
564 }
565 }
567 image4,
568 new Rectangle(0, 0, image4.Width, image4.Height),
569 new Vector3(1f, 0f, 0f),
570 new Vector3(0f, 0f, 1f),
571 new Vector3(0f, 1f, 0f),
572 new Vector3(bounds.Left, m, 0f),
573 color,
574 alphaThreshold
575 );
576 }
577 for (int num = bounds.Top; num < bounds.Bottom; num++) {
578 Image image5 = new(bounds.Width, 1);
579 for (int num2 = bounds.Left; num2 < bounds.Right; num2++) {
580 if (num == bounds.Bottom - 1
581 || image.GetPixelFast(num2, num + 1).A <= alphaThreshold) {
582 image5.SetPixelFast(num2 - bounds.Left, 0, image.GetPixelFast(num2, num));
583 }
584 }
586 image5,
587 new Rectangle(0, 0, image5.Width, image5.Height),
588 new Vector3(1f, 0f, 0f),
589 new Vector3(0f, 0f, 1f),
590 new Vector3(0f, -1f, 0f),
591 new Vector3(bounds.Left, num + 1, 0f),
592 color,
593 alphaThreshold
594 );
595 }
596 for (int num3 = count; num3 < Vertices.Count; num3++) {
597 Vertices.Array[num3].Position.X -= (bounds.Left + bounds.Right) / 2f;
598 Vertices.Array[num3].Position.Y -= (bounds.Top + bounds.Bottom) / 2f;
599 Vertices.Array[num3].Position.Z -= 0.5f;
600 Vertices.Array[num3].Position.X *= scale.X;
601 Vertices.Array[num3].Position.Y *= 0f - scale.Y;
602 Vertices.Array[num3].Position.Z *= scale.Z;
603 Vertices.Array[num3].TextureCoordinates.X /= image.Width;
604 Vertices.Array[num3].TextureCoordinates.Y /= image.Height;
605 Vertices.Array[num3].Color *= color;
606 }
607 }
608
609 public virtual void AppendImageExtrusionSlice(Image slice,
610 Rectangle bounds,
611 Vector3 right,
612 Vector3 up,
613 Vector3 forward,
614 Vector3 position,
615 Color color,
616 int alphaThreshold) {
617 int num = int.MaxValue;
618 int num2 = int.MaxValue;
619 int num3 = int.MinValue;
620 int num4 = int.MinValue;
621 for (int i = bounds.Top; i < bounds.Bottom; i++) {
622 for (int j = bounds.Left; j < bounds.Right; j++) {
623 if (slice.GetPixelFast(j, i).A > alphaThreshold) {
624 num = MathUtils.Min(num, j);
625 num2 = MathUtils.Min(num2, i);
626 num3 = MathUtils.Max(num3, j);
627 num4 = MathUtils.Max(num4, i);
628 }
629 }
630 }
631 if (num != int.MaxValue) {
632 Matrix m = new(
633 right.X,
634 right.Y,
635 right.Z,
636 0f,
637 up.X,
638 up.Y,
639 up.Z,
640 0f,
641 forward.X,
642 forward.Y,
643 forward.Z,
644 0f,
645 position.X,
646 position.Y,
647 position.Z,
648 1f
649 );
650 bool flip = m.Determinant() > 0f;
651 float s = LightingManager.CalculateLighting(-forward);
652 Vector3 p = Vector3.Transform(new Vector3(num, num2, 0f), m);
653 Vector3 p2 = Vector3.Transform(new Vector3(num3 + 1, num2, 0f), m);
654 Vector3 p3 = Vector3.Transform(new Vector3(num, num4 + 1, 0f), m);
655 Vector3 p4 = Vector3.Transform(new Vector3(num3 + 1, num4 + 1, 0f), m);
657 p,
658 p2,
659 p3,
660 p4,
661 forward,
662 flip,
663 Color.MultiplyColorOnly(color, s)
664 );
665 }
666 }
667
668 public virtual void AppendImageExtrusionRectangle(Vector3 p11,
669 Vector3 p21,
670 Vector3 p12,
671 Vector3 p22,
672 Vector3 forward,
673 bool flip,
674 Color color) {
675 int count = Vertices.Count;
676 Vertices.Count += 4;
677 int index = Vertices.Count - 4;
678 BlockMeshVertex value = new() { Position = p11, TextureCoordinates = p11.XY + forward.XY / 2f, Color = color };
679 Vertices[index] = value;
680 int index2 = Vertices.Count - 3;
681 value = new BlockMeshVertex { Position = p21, TextureCoordinates = p21.XY + forward.XY / 2f, Color = color };
682 Vertices[index2] = value;
683 int index3 = Vertices.Count - 2;
684 value = new BlockMeshVertex { Position = p12, TextureCoordinates = p12.XY + forward.XY / 2f, Color = color };
685 Vertices[index3] = value;
686 int index4 = Vertices.Count - 1;
687 value = new BlockMeshVertex { Position = p22, TextureCoordinates = p22.XY + forward.XY / 2f, Color = color };
688 Vertices[index4] = value;
689 Indices.Count += 6;
690 if (flip) {
691 Indices[^6] = count;
692 Indices[^5] = count + 2;
693 Indices[^4] = count + 1;
694 Indices[^3] = count + 2;
695 Indices[^2] = count + 3;
696 Indices[^1] = count + 1;
697 }
698 else {
699 Indices[^6] = count;
700 Indices[^5] = count + 1;
701 Indices[^4] = count + 2;
702 Indices[^3] = count + 2;
703 Indices[^2] = count + 1;
704 Indices[^1] = count + 3;
705 }
706 }
707 }
708}
Engine.Vector3 Vector3
ReadOnlyList< VertexElement > VertexElements
static int Min(int x1, int x2)
static int Max(int x1, int x2)
Rgba32 SetPixelFast(int x, int y, Rgba32 color)
Rgba32 GetPixelFast(int x, int y)
virtual void TransformTextureCoordinates(Matrix matrix, int facesMask=-1)
static T[] GetVertexData< T >(VertexBuffer vertexBuffer)
static T[] GetIndexData< T >(IndexBuffer indexBuffer)
virtual void AppendImageExtrusionRectangle(Vector3 p11, Vector3 p21, Vector3 p12, Vector3 p22, Vector3 forward, bool flip, Color color)
virtual void AppendImageExtrusion(Image image, Rectangle bounds, Vector3 scale, Color color, int alphaThreshold)
virtual void ModulateColor(Color color, int facesMask=-1)
virtual void BlendBlockMesh(BlockMesh blockMesh, float factor)
virtual void AppendImageExtrusion(Image image, Rectangle bounds, Vector3 size, Color color)
static bool IsNear(float v1, float v2, float v3, float t)
DynamicArray< sbyte > Sides
virtual void Trim()
virtual void GenerateSidesData()
virtual void TransformPositions(Matrix matrix, int facesMask=-1)
virtual void SetColor(Color color, int facesMask=-1)
virtual BoundingBox CalculateBoundingBox(Matrix matrix)
virtual BoundingBox CalculateBoundingBox()
virtual void AppendImageExtrusionSlice(Image slice, Rectangle bounds, Vector3 right, Vector3 up, Vector3 forward, Vector3 position, Color color, int alphaThreshold)
static Matrix GetBoneAbsoluteTransform(ModelBone modelBone)
DynamicArray< BlockMeshVertex > Vertices
virtual void AppendBlockMesh(BlockMesh blockMesh)
DynamicArray< int > Indices
virtual void AppendModelMeshPart(ModelMeshPart meshPart, Matrix matrix, bool makeEmissive, bool flipWindingOrder, bool doubleSided, bool flipNormals, Color color)
static float CalculateLighting(Vector3 normal)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static Color MultiplyColorOnly(Color c, float s)
float Determinant()
bool Contains(Point2 p)
static Vector2 Transform(Vector2 v, Matrix m)
static Vector3 Lerp(Vector3 v1, Vector3 v2, float f)
static Vector3 TransformNormal(Vector3 v, Matrix m)
static Vector3 Transform(Vector3 v, Matrix m)
static Vector3 Normalize(Vector3 v)
static int Vector3ToFace(Vector3 v, int maxFace=5)