У меня возникли проблемы с моей головой вокруг системы цветов и материалов проектов C# WPF, в настоящее время я обновляю цвет всей системы точек на каждом обновление модели, когда я хотел бы просто обновить цвет одной точки (как она добавлена).Обновить цвет единственной точки GeometryModel3D Материал, а не целая система точек
AggregateSystem Класс
public class AggregateSystem {
// stack to store each particle in aggregate
private readonly Stack<AggregateParticle> particle_stack;
private readonly GeometryModel3D particle_model;
// positions, indices and texture co-ordinates for particles
private readonly Point3DCollection particle_positions;
private readonly Int32Collection triangle_indices;
private readonly PointCollection text_coords;
// brush to apply to particle_model.Material
private RadialGradientBrush rad_brush;
// ellipse for rendering
private Ellipse ellipse;
private RenderTargetBitmap render_bitmap;
public AggregateSystem() {
particle_stack = new Stack<AggregateParticle>();
particle_model = new GeometryModel3D { Geometry = new MeshGeometry3D() };
ellipse = new Ellipse {
Width = 32.0,
Height = 32.0
};
rad_brush = new RadialGradientBrush();
// fill ellipse interior using rad_brush
ellipse.Fill = rad_brush;
ellipse.Measure(new Size(32,32));
ellipse.Arrange(new Rect(0,0,32,32));
render_bitmap = new RenderTargetBitmap(32,32,96,96,PixelFormats.Pbgra32));
ImageBrush img_brush = new ImageBrush(render_bitmap);
DiffuseMaterial diff_mat = new DiffuseMaterial(img_brush);
particle_model.Material = diff_mat;
particle_positions = new Point3DCollection();
triangle_indices = new Int32Collection();
tex_coords = new PointCollection();
}
public Model3D AggregateModel => particle_model;
public void Update() {
// get the most recently added particle
AggregateParticle p = particle_stack.Peek();
// compute position index for triangle index generation
int position_index = particle_stack.Count * 4;
// create points associated with particle for circle generation
Point3D p1 = new Point3D(p.position.X, p.position.Y, p.position.Z);
Point3D p2 = new Point3D(p.position.X, p.position.Y + p.size, p.position.Z);
Point3D p3 = new Point3D(p.position.X + p.size, p.position.Y + p.size, p.position.Z);
Point3D p4 = new Point3D(p.position.X + p.size, p.position.Y, p.position.Z);
// add points to particle positions collection
particle_positions.Add(p1);
particle_positions.Add(p2);
particle_positions.Add(p3);
particle_positions.Add(p4);
// create points for texture co-ords
Point t1 = new Point(0.0, 0.0);
Point t2 = new Point(0.0, 1.0);
Point t3 = new Point(1.0, 1.0);
Point t4 = new Point(1.0, 0.0);
// add texture co-ords points to texcoords collection
tex_coords.Add(t1);
tex_coords.Add(t2);
tex_coords.Add(t3);
tex_coords.Add(t4);
// add position indices to indices collection
triangle_indices.Add(position_index);
triangle_indices.Add(position_index + 2);
triangle_indices.Add(position_index + 1);
triangle_indices.Add(position_index);
triangle_indices.Add(position_index + 3);
triangle_indices.Add(position_index + 2);
// update colour of points - **NOTE: UPDATES ENTIRE POINT SYSTEM**
// -> want to just apply colour to single particles added
rad_brush.GradientStops.Add(new GradientStop(p.colour, 0.0));
render_bitmap.Render(ellipse);
// set particle_model Geometry model properties
((MeshGeometry3D)particle_model.Geometry).Positions = particle_positions;
((MeshGeometry3D)particle_model.Geometry).TriangleIndices = triangle_indices;
((MeshGeometry3D)particle_model.Geometry).TextureCoordinates = tex_coords;
}
public void SpawnParticle(Point3D _pos, Color _col, double _size) {
AggregateParticle agg_particle = new AggregateParticle {
position = _pos, colour = _col, size = _size;
}
// push most-recently-added particle to stack
particle_stack.Push(agg_particle);
}
}
, где AggregateParticle
класс СТРУЧОК, состоящий из Point3D position
, Color color
и double size
полей, которые самоочевидны.
Есть ли простой и эффективный способ обновления цвета одиночной частицы, поскольку она добавлена в метод Update
, а не всей системы частиц? Или мне нужно создать List
(или подобную структуру данных) экземпляров DiffuseMaterial
для каждой частицы в системе и применить кисти для нужного цвета для каждого?
[Последнее - это то, чего я хочу избежать любой ценой, отчасти из-за того, что это потребует больших структурных изменений для моего кода, и я уверен, что есть лучший способ приблизиться к этому, то есть там ДОЛЖЕН быть каким-то простым способом применить цвет к набору текстурных координат, конечно ?!.]
Дальнейшие подробности
AggregateModel
является однойModel3D
экземпляр, соответствующий полюparticle_model
, который добавляется кModel3DGroup
изMainWindow
.Я должен отметить, что то, чего я пытаюсь достичь, в частности, является «градиентом» цветов для каждой частицы в агрегатной структуре, где частица имеет
Color
в «температурном градиенте» (рассчитанном в другом месте в программа), которая зависит от порядка, в котором она была сгенерирована, т.е. частицы имеют более холодный цвет, если они сгенерированы ранее, и более теплый цвет, если он создан позже. Этот список цветов предварительно вычисляется и передается каждой частице в методеUpdate
, как это видно выше.В одном решении я попытался создать отдельный экземпляр
AggregateComponent
для каждой частицы, где каждый из этих объектов имеет ассоциированныйModel3D
и, следовательно, соответствующую кисть. Затем был создан классAggregateComponentManager
, который содержалList
каждогоAggregateComponent
. Это решение работает, однако это ужасно медленно, так как каждый компонент должен обновляться каждый раз, когда добавляется частица, так что потребление памяти взрывается - есть ли способ адаптировать это, когда я могу кэшировать уже сделанныеAggregateComponent
с без необходимости их методаUpdate
время добавления частицы?
Полный исходный код (C# код в каталоге DLAProject
) можно найти на GitHub: https://github.com/SJR276/DLAProject
@EvilTak Но тогда как этот массив 'Material' может быть применен к одному экземпляру' particle_model' 'AggregateSystem'? Насколько мне известно, «GeometryModel3D» принимает только один экземпляр «Material». – ArchbishopOfBanterbury
Извините, это было недоразумение с моей стороны. Читайте дальше: Я не понимаю, что вы пытаетесь сделать здесь. Вы внедряете систему частиц? Если это так, я бы рекомендовал использовать отдельные модели (технически только треугольник или квадрат) для каждого «Particle» и обработки рендеринга для каждой частицы отдельно. – EvilTak
@EvilTak Да, это, по сути, система частиц (со специальными свойствами), которая реализуется. Понимаю, мне придется взглянуть на этот тип решения. Я добавил ссылку на полный исходный код github, если вы хотите увидеть остальную часть структуры проекта, здесь слишком много кода для публикации. – ArchbishopOfBanterbury