利用者:Sionix/SummerOfCode2006/Clouds
目次
Clouds
[ Back to the project ] [ http://sionix.pbwiki.com/SummerOfCode2006_Screenshots ]
How it works and User interface
Cloud building is based on modelling cloud shapes via closed meshes.
Basic steps are:
1. Create cloud shape
2. Fill shape with particles
Usage examples
Programming interface
Integration into pipeline
Cloud part of SkyGen is integrated into three Blender areas:
- 3D browser
- UI
- convertblender
3D browser is provided with draw_cloud function that displays draft view of the cloud.
void draw_cloud(Object *ob, CloudEff *clf)
draw_cloud:
@param[in] ob Mesh object. @param[in] clf Cloud effect, attached to the mesh.
UI - buttons_object is provided with cloud panel
void object_panel_clouds(Object *ob)
object_panel_clouds:
@param[in] ob Mesh object.
convertblender is the place where all cloud conversion processes are playing their roles. render_cloud converts CloudEff to the particle set.
void render_cloud(Render *re, Object *ob, CloudEff *clf)
render_cloud:
@param[in] re Main Render database. @param[in] ob Mesh object with cloud. @param[in] clf Cloud effect attached to the mesh.
Objects and relations
DNA objects
The following structure represents a single cloud object attached to the mesh. It behaves almost the same as PartEff.
First fields are for general effect purposes.
typedef struct CloudEff { struct CloudEff *next, *prev; short type, flag, buttype, stype, vertgroup, userjit;
Following are for particle control.
int totpart, totkey, seed; float imat[4][4];
Next fields are pure cloud-specific:
// Cell size in world metrics. float cell_size; // Possibilities for vertical dissolving. float pos_solid, pos_vapor, pos_none; // Particle density at top and bottom layers. float dens_top, dens_bottom; // Scattering params. float scat_start, scat_end, scat_width; // Texture mapping type and texture id. short eff_type, tex_id; // Blur multiplicitier. short blur_cnt, pad1; // Build check - mesh "hash" value based on geometry. float build_check;
Last ones represent particle data itself.
Particle *keys; struct Group *group; } CloudEff;
Interface functions
Library C interface functions for using in other Blender modules.
void BSG_prepareCloudParticles(struct Object *ob, struct Object *camera, struct World *wrld, struct CloudEff *clf, short stages);
BSG_prepareCloudParticles:
@param[in] ob Mesh object - cloud shape. @param[in] camera Current scene camera. @param[in] wrld Current World object. @param[in, out] clf Cloud effect object to be processed. @param[in] stages Build stages to perform.
Flags to define cloud build stages:
// Perform only creation and arrangement step. #define BUILD_STAGES_BUILD 1 // Perform light tracing and setup particles colors. #define BUILD_STAGES_LIT 2 // Perform all stages. #define BUILD_STAGES_ALL 0xff
Auxiliary templates
Ref<T> - Class-holder for smart pointers system. Used for automatic control for object destruction.
Array<T> - Helper dynamic array class, similar to STL's.
Auxiliary mathematics
Classes for geometry calculations.
ConvexMesh class provides functionality for mesh processing.
Note 1: 'ConvexMesh' name is not fully correct now, class does not represents a convex mesh.
Note 2: There is some rudimentary functionality, that was used during several implementation tests and is not deleted while (I am not including TrgOctree class into this description, because it is not used in the pipeline now)
class ConvexMesh { public: ConvexMesh(); void BuildMesh(TArray<Vect3f> *new_verts, float *verts, unsigned int *trgs, int numv, int numt); bool PointContains(const Vect3f &p); void GetAABB(Vect3f &vmin, Vect3f &vmax); inline Vect3f GetCenter(); const ConvexMesh &operator =(const ConvexMesh &cvm); static void SplitToConvexMeshes(TArray<ConvexMesh> &cvms, float *_verts, unsigned int *_trgs, int _num_verts, int _num_trgs, bool only_closed_sep = false); void GetOwnData(TArray<float> &v, TArray<unsigned int> &t); inline float *Vertices(); inline unsigned int *Triangles(); inline int VerticesLength(); inline int TrianglesLength(); int GetIntersectionsCount(const Vect3f &sp, const Vect3f &ep); protected: static void BuildNeighbourGraph(); static int TraceNeighbour(int cur, int set_val); static void TestAndGetConvex(TArray<ConvexMesh> &cvms, TArray<Vect3f> *new_verts, int cur_marker, int mark_len); static void TraceConvex(TArray<int> &conv_mark_trgs, TArray<int> &border_trgs, int curt, int cur_marker); private: Ref<TArray<Vect3f> > m_verts; TArray<unsigned int> m_trgs; TArray<Vect3f> m_normals; Vect3f m_center; Ref<TrgOctree> m_octree; // Temp data static float *verts; static unsigned int *trgs; static int num_verts; static int num_trgs; static TArray<int> neigh_trgs; static TArray<int> mark_trgs; };
Public methods:
/// Default constructor. ConvexMesh::ConvexMesh() /// Assign vertex and triangles data to the object. /// @param[in, out] new_verts Pointer to the vertex cache - shared /// between several ConvexMesh objects parent data. /// @param[in] verts Pointer to the vertices data - length is 3 * numv. /// @param[in] trgs Pointer to the triangles data - length is numt. /// @param[in] numv Number of vertices. /// @param[in] numt Number of triangles * 3. void ConvexMesh::BuildMesh(TArray<Vect3f> *new_verts, float *verts, unsigned int *trgs, int numv, int numt) /// Detect whether convex object contains a point. /// @param[in] p A point. /// @return True if point is inside of a convex object. bool ConvexMesh::PointContains(const Vect3f &p) /// Get axis aligned bounding box for the object. /// @param[out] vmin Lower-left-near corner's coordinates. /// @param[out] vmax Upper-right-far corner's coordinates. void ConvexMesh::GetAABB(Vect3f &vmin, Vect3f &vmax) /// Get object's center of mass. /// @return Center location. Vect3f ConvexMesh::GetCenter() /// Assignment operator. /// @param[in] cvm Object to copy from. /// @return Constant reference to this object. const ConvexMesh &ConvexMesh::operator =(const ConvexMesh &cvm) /// The main function. Constructs array of ConvexMeshes from initial geometry /// data. /// @param[out] cvms Resulting array of ConvexMesh objects. /// @param[in] _verts Pointer to vertices data, length is _num_verts * 3 /// @param[in] _trgs Pointer to triangles data. /// @param[in] _num_verts Number of vertices. /// @param[in] _num_trgs Number of triangles * 3. /// @param[in] only_closed_sep Split only by closed parts. static void ConvexMesh::SplitToConvexMeshes(TArray<ConvexMesh> &cvms, float *_verts, unsigned int *_trgs, int _num_verts, int _num_trgs, bool only_closed_sep) /// Get geometry data. /// @param[out] v Vertices. /// @param[out] t Triangles. void ConvexMesh::GetOwnData(TArray<float> &v, TArray<unsigned int> &t) /// Quick access to data. float *ConvexMesh::Vertices() unsigned int *ConvexMesh::Triangles() int ConvexMesh::VerticesLength() int ConvexMesh::TrianglesLength() /// Calculate ConvexMesh vs segmet intersections count. /// @param[in] sp Segment start point. /// @param[in] ep Segment end point. /// @return Count of intersections. int ConvexMesh::GetIntersectionsCount(const Vect3f &sp, const Vect3f &ep)
Class CellBox provides voxelization functionality.
It has three-dimensional matrix to hold particles' ids.
class CellBox { public: CellBox(); ~CellBox(); bool Allocate(int _x, int _y, int _z); void Clear(); void Set(int v); inline int &operator ()(int i, int j, int k); inline float &Height(int i, int j); inline int X(); inline int Y(); inline int Z(); inline int DataSize(); private: int *data; float *height; int x, y, z; };
Methods description:
/// Default constructor. CellBox::CellBox() /// Destructor. ~CellBox::CellBox() /// Allocate memory for a cellbox with given dimensions. /// @param[in] _x Size by X axis. /// @param[in] _y Size by Y axis. /// @param[in] _z Size by Z axis. /// @return True if allocation succeeded. bool CellBox::Allocate(int _x, int _y, int _z) /// Clear data, free memory. void CellBox::Clear() /// Set all the elements to given value. /// @param[in] v Value to set. void CellBox::Set(int v); /// Get an access to the specified cell. /// @param[in] i Coordinate by X axis. /// @param[in] j Coordinate by Y axis. /// @param[in] k Coordinate by Z axis. /// @return Reference to element. int &CellBox::operator ()(int i, int j, int k) /// Get cellbox height (by Z axis) in range [0; 1]. /// @param[in] i Coordinate by X axis. /// @param[in] j Coordinate by Y axis. /// @return Reference to height value. float &CellBox::Height(int i, int j) /// Get cellbox's sizes. int CellBox::X() int CellBox::Y() int CellBox::Z() int CellBox::DataSize()
Cloud engine
Class CloudEngine is a main class in Cloud modelling system. Used for forming and maintaining single scene cloud object (CloudEff).
class CloudEngine { public: CloudEngine(); ~CloudEngine(); public: struct Particle { Vect3f v; float a, r, g, b; float size; }; struct ScatParams { enum Type { LINEAR = 0, QUAD = 1, POLY_05 = 2 }; Type type; float a, b, c; float width; }; enum HorMapType // bits { HEIGHT = 1, POSSIBILITY = 2 }; public: // Get cell size inline float &CellSize(); // Get result particles count inline int NumData(); // Get result particles positions inline Particle *GetData(); inline ScatParams &GetScatParams(); // Set proper cell size before call inline void SetBlurFactor(float val); // Arrange particles inside of mesh. void BuildParticles(float *verts, unsigned int *trgs, int num_verts, int num_trgs); // Rebuild particles from array. void RebuildParticles(const TArray<Vect3f> &parts); // Remove invisible particles. void ClearupParticles(); // Apply light settings to shade particles. void ApplyLighting(const Vect3f &dir, const Vect3f &view_dir, const Vect3f &color, const Vect3f &back_color, const Vect3f &sun_color); // Dissolve particles vertically. void DissolveVerticalLayers(const ScatParams &pps, const ScatParams &height_density); // Apply height map. void ApplyHorDissolveMap(const ScatParams &col, unsigned int *cmap, short map_w, short map_h, unsigned int type); protected: void ClearData(); float TraceRayFromCell(const Vect3f &dir, int i, int j, int k); void TraceCollectFromCell(TArray<Vect3f> &res, const Vect3f &dir, int i, int j, int k); float Scattering(float dist, const ScatParams &sp); float CalcDensity(int i, int j, int k); float GetDensity(int imax, int i, int j, int k); float DensityWeightFunc(int di, int dj, int dk); float DensityFieldFunc(float distr, float maxr); private: // Cell size in world units float m_cell_size; // Max radius used in density calculations float m_max_rad; // Particles TArray<Particle> m_parts; // AABB Vect3f bbmin, bbmax; CellBox cell_box; ScatParams scat_params; // Working array (for speedup) TArray<float> part_density; };
Public functionality:
/// Constructor. CloudEngine::CloudEngine() /// Destructor. CloudEngine::~CloudEngine() /// Get cell size member. /// @return Reference to cellsize member. float &CloudEngine::CellSize() /// Get result particles count. /// @return Particles count. int CloudEngine::NumData() /// Get result particles positions. /// @return Pointer to the result data. Particle *CloudEngine::GetData() /// Get access to scattering params. /// @return Reference to scat_params member. ScatParams &CloudEngine::GetScatParams() /// Set blur multiplicier. /// Note: Set proper cell size before call. /// @param[in] val New value. void CloudEngine::SetBlurFactor(float val) /// Arrange particles inside of mesh. /// @param[in] verts Mesh vertices. /// @param[in] trgs Mesh triangles. /// @param[in] num_verts Vertices count. /// @param[in] num_trgs Triangles count * 3. void CloudEngine::BuildParticles(float *verts, unsigned int *trgs, int num_verts, int num_trgs) /// Rebuild particles from array. Avoid full list rebuild. /// @param[in] parts Particles positions. void CloudEngine::RebuildParticles(const TArray<Vect3f> &parts) /// Remove invisible particles. void CloudEngine::ClearupParticles(); /// Apply light settings to shade particles. /// @param[in] dir Direction to the sun. /// @param[in] view_dir Current observer's viewing direction. /// @param[in] color Cloud color. /// @param[in] back_color Background color. /// @param[in] sun_color Sun color. void CloudEngine::ApplyLighting(const Vect3f &dir, const Vect3f &view_dir, const Vect3f &color, const Vect3f &back_color, const Vect3f &sun_color) /// Dissolve particles vertically. /// @param[in] pps Scattering params. /// @param[in] height_density Params for height density. void CloudEngine::DissolveVerticalLayers(const ScatParams &pps, const ScatParams &height_density) /// Apply height map. /// @param[in] col Scattering for color. /// @param[in] cmap Color map. /// @param[in] map_w Map width. /// @param[in] map_h Map height. /// @param[in] type Map type (HEIGHT or POSSIBILITY). void CloudEngine::ApplyHorDissolveMap(const ScatParams &col, unsigned int *cmap, short map_w, short map_h, unsigned int type)
Folders structure
soc-blender/ projectfiles_vc7/ blender/ BSG_SkyGen/ BSG_SkyGen.vcproj source/ blender/ BSG_SkyGen/ BSG_SkyGen.h // Interface header intern/ BSG_SkyGen.cpp // Interface functions implementation // Common modules sky_math.h // Auxiliary math sky_math.cpp ref.h // Auxiliary templates array.h // Cloud module CloudEngine.h CloudEngine.cpp ...