diff options
Diffstat (limited to 'source')
237 files changed, 8974 insertions, 2897 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index fb6505fe935..8a71c3de86b 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -97,17 +97,58 @@ void blf_font_size(FontBLF *font, int size, int dpi) } } +static void blf_font_ensure_ascii_table(FontBLF *font) +{ + /* build ascii on demand */ + if(font->glyph_cache->glyph_ascii_table['0']==NULL) { + GlyphBLF **glyph_ascii_table= font->glyph_cache->glyph_ascii_table; + GlyphBLF *g; + unsigned int i; + for(i=0; i<256; i++) { + g= blf_glyph_search(font->glyph_cache, i); + if (!g) { + FT_UInt glyph_index= FT_Get_Char_Index(font->face, i); + g= blf_glyph_add(font, glyph_index, i); + } + glyph_ascii_table[i]= g; + } + } +} + +/* Fast path for runs of ASCII characters. Given that common UTF-8 + * input will consist of an overwhelming majority of ASCII + * characters. + */ + +/* Note, + * blf_font_ensure_ascii_table(font); must be called before this macro */ + +#define BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table) \ + if(((c)= (str)[i]) < 0x80) { \ + g= glyph_ascii_table[c]; \ + i++; \ + } \ + else if ((c= blf_utf8_next((unsigned char *)(str), &(i)))) { \ + if ((g= blf_glyph_search((font)->glyph_cache, c)) == NULL) { \ + g= blf_glyph_add(font, FT_Get_Char_Index((font)->face, c), c); \ + } \ + } \ + + + void blf_font_draw(FontBLF *font, const char *str, unsigned int len) { unsigned int c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; int pen_x, pen_y; - int i, has_kerning, st; + int has_kerning, st; + unsigned int i; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; i= 0; pen_x= 0; @@ -115,17 +156,15 @@ void blf_font_draw(FontBLF *font, const char *str, unsigned int len) has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; + blf_font_ensure_ascii_table(font); + while (str[i] && i < len) { - c= blf_utf8_next((unsigned char *)str, &i); + + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); + if (c == 0) break; - g= blf_glyph_search(font->glyph_cache, c); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, c); - g= blf_glyph_add(font, glyph_index, c); - } - /* if we don't found a glyph, skip it. */ if (!g) continue; @@ -157,32 +196,23 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, unsigned int len) char c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; int pen_x, pen_y; - int i, has_kerning, st; + int has_kerning, st; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; pen_x= 0; pen_y= 0; has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; - /* build ascii on demand */ - if(font->glyph_ascii_table['0']==NULL) { - for(i=0; i<256; i++) { - g= blf_glyph_search(font->glyph_cache, i); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, i); - g= blf_glyph_add(font, glyph_index, i); - } - font->glyph_ascii_table[i]= g; - } - } - + blf_font_ensure_ascii_table(font); + while ((c= *(str++)) && len--) { - g= font->glyph_ascii_table[c]; + g= font->glyph_cache->glyph_ascii_table[c]; /* if we don't found a glyph, skip it. */ if (!g) @@ -216,13 +246,15 @@ void blf_font_buffer(FontBLF *font, const char *str) unsigned char b_col_char[4]; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; float a, *fbuf; int pen_x, y, x; - int i, has_kerning, st, chx, chy; + int has_kerning, st, chx, chy; + unsigned int i; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache || (!font->b_fbuf && !font->b_cbuf)) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; i= 0; pen_x= (int)font->pos[0]; @@ -234,18 +266,16 @@ void blf_font_buffer(FontBLF *font, const char *str) b_col_char[2]= font->b_col[2] * 255; b_col_char[3]= font->b_col[3] * 255; + blf_font_ensure_ascii_table(font); + while (str[i]) { int pen_y; - c= blf_utf8_next((unsigned char *)str, &i); + + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); + if (c == 0) break; - g= blf_glyph_search(font->glyph_cache, c); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, c); - g= blf_glyph_add(font, glyph_index, c); - } - /* if we don't found a glyph, skip it. */ if (!g) continue; @@ -363,13 +393,15 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) unsigned int c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; rctf gbox; int pen_x, pen_y; - int i, has_kerning, st; + int has_kerning, st; + unsigned int i; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; box->xmin= 32000.0f; box->xmax= -32000.0f; @@ -382,17 +414,15 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; + blf_font_ensure_ascii_table(font); + while (str[i]) { - c= blf_utf8_next((unsigned char *)str, &i); + + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); + if (c == 0) break; - g= blf_glyph_search(font->glyph_cache, c); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, c); - g= blf_glyph_add(font, glyph_index, c); - } - /* if we don't found a glyph, skip it. */ if (!g) continue; @@ -534,7 +564,7 @@ void blf_font_free(FontBLF *font) static void blf_font_fill(FontBLF *font) { - int i; + unsigned int i; font->aspect[0]= 1.0f; font->aspect[1]= 1.0f; @@ -568,8 +598,6 @@ static void blf_font_fill(FontBLF *font) font->b_col[2]= 0; font->b_col[3]= 0; font->ft_lib= ft_lib; - - memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table)); } FontBLF *blf_font_new(const char *name, const char *filename) diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index e165012f43e..9b39cb65cba 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -74,7 +74,6 @@ GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, int size, int dpi) GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) { GlyphCacheBLF *gc; - int i; gc= (GlyphCacheBLF *)MEM_mallocN(sizeof(GlyphCacheBLF), "blf_glyph_cache_new"); gc->next= NULL; @@ -82,10 +81,8 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) gc->size= font->size; gc->dpi= font->dpi; - for (i= 0; i < 257; i++) { - gc->bucket[i].first= NULL; - gc->bucket[i].last= NULL; - } + memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table)); + memset(gc->bucket, 0, sizeof(gc->bucket)); gc->textures= (GLuint *)malloc(sizeof(GLuint)*256); gc->ntex= 256; @@ -136,7 +133,9 @@ void blf_glyph_cache_clear(FontBLF *font) } } - memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table)); + if(font->glyph_cache) { + memset(font->glyph_cache->glyph_ascii_table, 0, sizeof(font->glyph_cache->glyph_ascii_table)); + } } void blf_glyph_cache_free(GlyphCacheBLF *gc) diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 9271d8d5a9e..ba0b9985dd4 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -40,7 +40,7 @@ struct rctf; unsigned int blf_next_p2(unsigned int x); unsigned int blf_hash(unsigned int val); -int blf_utf8_next(unsigned char *buf, int *iindex); +int blf_utf8_next(unsigned char *buf, unsigned int *iindex); char *blf_dir_search(const char *file); char *blf_dir_metrics_search(const char *filename); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index c4e192626e8..9840e6446ef 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -46,6 +46,9 @@ typedef struct GlyphCacheBLF { /* and the glyphs. */ ListBase bucket[257]; + /* fast ascii lookup */ + struct GlyphBLF *glyph_ascii_table[256]; + /* texture array, to draw the glyphs. */ GLuint *textures; @@ -184,9 +187,6 @@ typedef struct FontBLF { /* current glyph cache, size and dpi. */ GlyphCacheBLF *glyph_cache; - - /* fast ascii lookip */ - GlyphBLF *glyph_ascii_table[256]; /* freetype2 lib handle. */ FT_Library ft_lib; diff --git a/source/blender/blenfont/intern/blf_util.c b/source/blender/blenfont/intern/blf_util.c index ab6b516787e..edd23ac1ba6 100644 --- a/source/blender/blenfont/intern/blf_util.c +++ b/source/blender/blenfont/intern/blf_util.c @@ -72,7 +72,7 @@ unsigned int blf_hash(unsigned int val) * The original name: imlib_font_utf8_get_next * more info here: http://docs.enlightenment.org/api/imlib2/html/ */ -int blf_utf8_next(unsigned char *buf, int *iindex) +int blf_utf8_next(unsigned char *buf, unsigned int *iindex) { /* Reads UTF8 bytes from 'buf', starting at 'index' and * returns the code point of the next valid code point. diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 744ed9dba9c..5b40fa5d758 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -55,7 +55,7 @@ void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy); void curvemapping_free(struct CurveMapping *cumap); struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap); -void curvemapping_set_black_white(struct CurveMapping *cumap, float *black, float *white); +void curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3]); #define CURVEMAP_SLOPE_NEGATIVE 0 #define CURVEMAP_SLOPE_POSITIVE 1 @@ -70,9 +70,9 @@ void curvemapping_changed(struct CurveMapping *cumap, int rem_doubles); float curvemap_evaluateF(struct CurveMap *cuma, float value); /* single curve, with table check */ float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value); -void curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin); -void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin); -void curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin); +void curvemapping_evaluate3F(struct CurveMapping *cumap, float vecout[3], const float vecin[3]); +void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]); +void curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]); void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf); void curvemapping_premultiply(struct CurveMapping *cumap, int restore); int curvemapping_RGBA_does_something(struct CurveMapping *cumap); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 88965d12e4a..85b6f8f78fb 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -89,7 +89,7 @@ void end_render_materials(struct Main *); int material_in_material(struct Material *parmat, struct Material *mat); -void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col); +void ramp_blend(int type, float *r, float *g, float *b, float fac, const float col[3]); /* copy/paste */ void clear_matcopybuf(void); diff --git a/source/blender/blenkernel/BKE_navmesh_conversion.h b/source/blender/blenkernel/BKE_navmesh_conversion.h new file mode 100644 index 00000000000..acb3c2963a9 --- /dev/null +++ b/source/blender/blenkernel/BKE_navmesh_conversion.h @@ -0,0 +1,64 @@ +/** +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#ifndef BKE_NAVMESH_CONVERSION_H +#define BKE_NAVMESH_CONVERSION_H + +struct DerivedMesh; + +/* navmesh_conversion.cpp */ +bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly, + int &nverts, float *&verts, + int &ndtris, unsigned short *&dtris, + int& npolys, unsigned short *&dmeshes, + unsigned short*& polys, int *&dtrisToPolysMap, + int *&dtrisToTrisMap, int *&trisToFacesMap); + +bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, + int &ntris, unsigned short *&tris, int *&trisToFacesMap, + int *&recastData); + +bool buildNavMeshData(const int nverts, const float* verts, + const int ntris, const unsigned short *tris, + const int* recastData, const int* trisToFacesMap, + int &ndtris, unsigned short *&dtris, + int &npolys, unsigned short *&dmeshes, unsigned short *&polys, + int &vertsPerPoly, int *&dtrisToPolysMap, int *&dtrisToTrisMap); + +bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short* polys, const unsigned short* dmeshes, + const float* verts, const unsigned short* dtris, + const int* dtrisToPolysMap); + +int polyNumVerts(const unsigned short* p, const int vertsPerPoly); +bool polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts); +int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx); +float distPointToSegmentSq(const float* point, const float* a, const float* b); + +#endif //NAVMESH_CONVERSION_H diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index cf68e5795b4..9cb4dfae534 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -45,8 +45,6 @@ struct Strip; struct StripElem; struct bSound; -#define MAXSEQ 32 - #define BUILD_SEQAR_COUNT_NOTHING 0 #define BUILD_SEQAR_COUNT_CURRENT 1 #define BUILD_SEQAR_COUNT_CHILDREN 2 diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index c1797427cc2..52709b75ca0 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -353,6 +353,16 @@ if(WITH_LZMA) add_definitions(-DWITH_LZMA) endif() +if(WITH_GAMEENGINE) + list(APPEND INC_SYS + ../../../extern/recastnavigation/Recast/Include + ) + list(APPEND SRC + intern/navmesh_conversion.cpp + BKE_navmesh_conversion.h + ) +endif() + if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") endif() diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 5ea42ee65ae..632188b2d86 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -1,7 +1,8 @@ #!/usr/bin/python Import ('env') +import os -sources = env.Glob('intern/*.c') +sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include' incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager' @@ -90,6 +91,12 @@ if env['WITH_BF_LZMA']: incs += ' #/extern/lzma' defs.append('WITH_LZMA') +if env['WITH_BF_GAMEENGINE']: + incs += ' #/extern/recastnavigation/Recast/Include' + defs.append('WITH_GAMEENGINE') +else: + sources.remove('intern' + os.sep + 'navmesh_conversion.cpp') + if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 4b6d51dfbda..bf77f8bc9c0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -648,13 +648,22 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditFace *efa; int i, draw; - + const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */ + + /* GL_ZERO is used to detect if drawing has started or not */ + GLenum poly_prev= GL_ZERO; + GLenum shade_prev= GL_ZERO; + (void)setMaterial; /* unused */ /* currently unused -- each original face is handled separately */ (void)compareDrawOptions; if (emdm->vertexCos) { + /* add direct access */ + float (*vertexCos)[3]= emdm->vertexCos; + float (*vertexNos)[3]= emdm->vertexNos; + float (*faceNos)[3]= emdm->faceNos; EditVert *eve; for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) @@ -664,75 +673,134 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us int drawSmooth = (efa->flag & ME_SMOOTH); draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); if(draw) { + const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES; if (draw==2) { /* enabled with stipple */ - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); + + if(poly_prev != GL_ZERO) glEnd(); + poly_prev= GL_ZERO; /* force glBegin */ + + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); } - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + if(skip_normals) { + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } + else { + const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT; + if (shade_type != shade_prev) { + glShadeModel((shade_prev= shade_type)); + } + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(emdm->faceNos[i]); - glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); - if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); - } else { - glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); - glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); - glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); - if(efa->v4) { - glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]); - glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); + if (!drawSmooth) { + glNormal3fv(faceNos[i]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } else { + glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + if(poly_type == GL_QUADS) { + glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } } } - glEnd(); + - if (draw==2) + if (draw==2) { + glEnd(); + poly_prev= GL_ZERO; /* force glBegin */ + glDisable(GL_POLYGON_STIPPLE); + } } } - } else { + } + else { for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { int drawSmooth = (efa->flag & ME_SMOOTH); draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); if(draw) { + const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES; if (draw==2) { /* enabled with stipple */ + + if(poly_prev != GL_ZERO) glEnd(); + poly_prev= GL_ZERO; /* force glBegin */ + glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipple_quarttone); } - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(efa->n); - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(efa->v4) glVertex3fv(efa->v4->co); - } else { - glNormal3fv(efa->v1->no); + if(skip_normals) { + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } glVertex3fv(efa->v1->co); - glNormal3fv(efa->v2->no); glVertex3fv(efa->v2->co); - glNormal3fv(efa->v3->no); glVertex3fv(efa->v3->co); - if(efa->v4) { - glNormal3fv(efa->v4->no); - glVertex3fv(efa->v4->co); + if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co); + } + else { + const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT; + if (shade_type != shade_prev) { + glShadeModel((shade_prev= shade_type)); + } + if(poly_type != poly_prev) { + if(poly_prev != GL_ZERO) glEnd(); + glBegin((poly_prev= poly_type)); + } + + if (!drawSmooth) { + glNormal3fv(efa->n); + glVertex3fv(efa->v1->co); + glVertex3fv(efa->v2->co); + glVertex3fv(efa->v3->co); + if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co); + } else { + glNormal3fv(efa->v1->no); + glVertex3fv(efa->v1->co); + glNormal3fv(efa->v2->no); + glVertex3fv(efa->v2->co); + glNormal3fv(efa->v3->no); + glVertex3fv(efa->v3->co); + if(poly_type == GL_QUADS) { + glNormal3fv(efa->v4->no); + glVertex3fv(efa->v4->co); + } } } - glEnd(); + - if (draw==2) + if (draw==2) { + glEnd(); + poly_prev= GL_ZERO; + glDisable(GL_POLYGON_STIPPLE); + } } } } + + /* if non zero we know a face was rendered */ + if(poly_prev != GL_ZERO) glEnd(); } static void emDM_drawFacesTex_common(DerivedMesh *dm, @@ -2528,13 +2596,13 @@ static void make_vertexcosnos__mapFunc(void *userData, int index, float *co, flo /* check if we've been here before (normal should not be 0) */ if(vec[3] || vec[4] || vec[5]) return; - VECCOPY(vec, co); + copy_v3_v3(vec, co); vec+= 3; if(no_f) { - VECCOPY(vec, no_f); + copy_v3_v3(vec, no_f); } else { - VECCOPY(vec, no_s); + normal_short_to_float_v3(vec, no_s); } } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index a0f38e675f9..3966caa1fa9 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -156,8 +156,8 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, if(rule->type == eBoidRuleType_Goal && boids->options & BOID_ALLOW_CLIMB && surface!=0.0f) { if(!bbd->goal_ob || bbd->goal_priority < priority) { bbd->goal_ob = eob; - VECCOPY(bbd->goal_co, efd.loc); - VECCOPY(bbd->goal_nor, efd.nor); + copy_v3_v3(bbd->goal_co, efd.loc); + copy_v3_v3(bbd->goal_nor, efd.nor); } } else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing && @@ -869,7 +869,7 @@ static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, { BoidParticle *bpa = pa->boid; float nor[3], vel[3]; - VECCOPY(nor, surface_nor); + copy_v3_v3(nor, surface_nor); /* gather apparent gravity */ VECADDFAC(bpa->gravity, bpa->gravity, surface_nor, -1.0f); @@ -1345,7 +1345,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { boid_climb(boids, pa, ground_co, ground_nor); //float nor[3]; - //VECCOPY(nor, ground_nor); + //copy_v3_v3(nor, ground_nor); ///* gather apparent gravity to r_ve */ //VECADDFAC(pa->r_ve, pa->r_ve, ground_nor, -1.0); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index c497cd2813a..c84a3cfc730 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -555,7 +555,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf if (texfall == 0) { dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); - VECCOPY(dstf, brush_rgb); + copy_v3_v3(dstf, brush_rgb); dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius); } else if (texfall == 1) { @@ -754,7 +754,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i for (x=origx; x < w; x++, bf+=4, mf+=4, tf+=4) { if (dotexold) { - VECCOPY(tf, otf); + copy_v3_v3(tf, otf); tf[3] = otf[3]; otf += 4; } @@ -926,7 +926,7 @@ static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pres brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure)); } -void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos) +void brush_jitter_pos(Brush *brush, float pos[2], float jitterpos[2]) { int use_jitter= brush->jitter != 0; @@ -949,7 +949,7 @@ void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos) jitterpos[1] = pos[1] + 2*rand_pos[1]*diameter*brush->jitter; } else { - VECCOPY2D(jitterpos, pos); + copy_v2_v2(jitterpos, pos); } } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 0dde94bc639..0cff6d75b6a 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1893,7 +1893,7 @@ void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3]) cddm->mvert = vert; for(i = 0; i < dm->numVertData; ++i, ++vert) - VECCOPY(vert->no, vertNormals[i]); + copy_v3_v3_short(vert->no, vertNormals[i]); } void CDDM_calc_normals(DerivedMesh *dm) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index ed073f03270..e0b7ebe1f44 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -104,11 +104,11 @@ BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert // fill tree for ( i = 0; i < numfaces; i++, tface++ ) { - VECCOPY ( &co[0*3], x[tface->v1].co ); - VECCOPY ( &co[1*3], x[tface->v2].co ); - VECCOPY ( &co[2*3], x[tface->v3].co ); + copy_v3_v3 ( &co[0*3], x[tface->v1].co ); + copy_v3_v3 ( &co[1*3], x[tface->v2].co ); + copy_v3_v3 ( &co[2*3], x[tface->v3].co ); if ( tface->v4 ) - VECCOPY ( &co[3*3], x[tface->v4].co ); + copy_v3_v3 ( &co[3*3], x[tface->v4].co ); BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) ); } @@ -133,21 +133,21 @@ void bvhtree_update_from_mvert ( BVHTree * bvhtree, MFace *faces, int numfaces, { for ( i = 0; i < numfaces; i++, mfaces++ ) { - VECCOPY ( &co[0*3], x[mfaces->v1].co ); - VECCOPY ( &co[1*3], x[mfaces->v2].co ); - VECCOPY ( &co[2*3], x[mfaces->v3].co ); + copy_v3_v3 ( &co[0*3], x[mfaces->v1].co ); + copy_v3_v3 ( &co[1*3], x[mfaces->v2].co ); + copy_v3_v3 ( &co[2*3], x[mfaces->v3].co ); if ( mfaces->v4 ) - VECCOPY ( &co[3*3], x[mfaces->v4].co ); + copy_v3_v3 ( &co[3*3], x[mfaces->v4].co ); // copy new locations into array if ( moving && xnew ) { // update moving positions - VECCOPY ( &co_moving[0*3], xnew[mfaces->v1].co ); - VECCOPY ( &co_moving[1*3], xnew[mfaces->v2].co ); - VECCOPY ( &co_moving[2*3], xnew[mfaces->v3].co ); + copy_v3_v3 ( &co_moving[0*3], xnew[mfaces->v1].co ); + copy_v3_v3 ( &co_moving[1*3], xnew[mfaces->v2].co ); + copy_v3_v3 ( &co_moving[2*3], xnew[mfaces->v3].co ); if ( mfaces->v4 ) - VECCOPY ( &co_moving[3*3], xnew[mfaces->v4].co ); + copy_v3_v3 ( &co_moving[3*3], xnew[mfaces->v4].co ); ret = BLI_bvhtree_update_node ( bvhtree, i, co, co_moving, ( mfaces->v4 ? 4 : 3 ) ); } @@ -550,7 +550,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM float temp[3], spf; // calculate tangential velocity - VECCOPY ( temp, collpair->normal ); + copy_v3_v3 ( temp, collpair->normal ); mul_v3_fl( temp, magrelVel ); VECSUB ( vrel_t_pre, relativeVelocity, temp ); @@ -2346,7 +2346,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision if ( verts[i].impulse_count ) { VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); - VECCOPY ( verts[i].impulse, tnull ); + copy_v3_v3 ( verts[i].impulse, tnull ); verts[i].impulse_count = 0; ret++; diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 9a6c2cc7e31..61e9daf4138 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -167,14 +167,14 @@ CurveMapping *curvemapping_copy(CurveMapping *cumap) return NULL; } -void curvemapping_set_black_white(CurveMapping *cumap, float *black, float *white) +void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3]) { int a; if(white) - VECCOPY(cumap->white, white); + copy_v3_v3(cumap->white, white); if(black) - VECCOPY(cumap->black, black); + copy_v3_v3(cumap->black, black); for(a=0; a<3; a++) { if(cumap->white[a]==cumap->black[a]) @@ -432,7 +432,7 @@ static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *nex /* in X, out Y. X is presumed to be outside first or last */ -static float curvemap_calc_extend(CurveMap *cuma, float x, float *first, float *last) +static float curvemap_calc_extend(CurveMap *cuma, float x, const float first[2], const float last[2]) { if(x <= first[0]) { if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0) { @@ -753,7 +753,7 @@ float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) } /* vector case */ -void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin) +void curvemapping_evaluate3F(CurveMapping *cumap, float vecout[3], const float vecin[3]) { vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]); vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]); @@ -761,7 +761,7 @@ void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *ve } /* RGB case, no black/white points, no premult */ -void curvemapping_evaluateRGBF(CurveMapping *cumap, float *vecout, const float *vecin) +void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3]) { vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0])); vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1])); @@ -770,7 +770,7 @@ void curvemapping_evaluateRGBF(CurveMapping *cumap, float *vecout, const float * /* RGB with black/white points and premult. tables are checked */ -void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const float *vecin) +void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3]) { float fac; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index b1beb6c449a..254629befd5 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -2547,9 +2547,9 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) sub_v3_v3v3(h2, p2, p2+3); len1= normalize_v3(h1); len2= normalize_v3(h2); - - vz= INPR(h1, h2); - + + vz= dot_v3v3(h1, h2); + if(leftviolate) { *(p2+3)= *(p2) - vz*len2*h1[0]; *(p2+4)= *(p2+1) - vz*len2*h1[1]; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index c342bbc917f..883f67c3061 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -867,7 +867,9 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, /* 23: CD_CLOTH_ORCO */ - {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} + {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 24: CD_RECAST */ + {sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL} }; static const char *LAYERTYPENAMES[CD_NUMTYPES] = { @@ -875,7 +877,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* 5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags", /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps", - /* 20-23 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco" + /* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast" }; const CustomDataMask CD_MASK_BAREMESH = @@ -883,14 +885,14 @@ const CustomDataMask CD_MASK_BAREMESH = const CustomDataMask CD_MASK_MESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | - CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS; + CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST; const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | - CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS; + CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST; const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO | - CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL; + CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL | CD_MASK_RECAST; const CustomDataMask CD_MASK_BMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_FACECORNERS = diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4b95c44f55f..468f39bf731 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -590,16 +590,16 @@ int closest_point_on_surface(SurfaceModifierData *surmd, float *co, float *surfa BLI_bvhtree_find_nearest(surmd->bvhtree->tree, co, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree); if(nearest.index != -1) { - VECCOPY(surface_co, nearest.co); + copy_v3_v3(surface_co, nearest.co); if(surface_nor) { - VECCOPY(surface_nor, nearest.no); + copy_v3_v3(surface_nor, nearest.no); } if(surface_vel) { MFace *mface = CDDM_get_face(surmd->dm, nearest.index); - VECCOPY(surface_vel, surmd->v[mface->v1].co); + copy_v3_v3(surface_vel, surmd->v[mface->v1].co); add_v3_v3(surface_vel, surmd->v[mface->v2].co); add_v3_v3(surface_vel, surmd->v[mface->v3].co); if(mface->v4) @@ -705,7 +705,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin sub_v3_v3v3(efd->loc, point->loc, translate); } else { - VECCOPY(efd->loc, ob->obmat[3]); + copy_v3_v3(efd->loc, ob->obmat[3]); } if(real_velocity) @@ -727,8 +727,8 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin mul_v3_fl(efd->vec_to_point, (efd->distance-eff->pd->f_size)/efd->distance); if(eff->flag & PE_USE_NORMAL_DATA) { - VECCOPY(efd->vec_to_point2, efd->vec_to_point); - VECCOPY(efd->nor2, efd->nor); + copy_v3_v3(efd->vec_to_point2, efd->vec_to_point); + copy_v3_v3(efd->nor2, efd->nor); } else { /* for some effectors we need the object center every time */ @@ -800,7 +800,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP strength= eff->pd->f_strength * efd->falloff; - VECCOPY(tex_co,point->loc); + copy_v3_v3(tex_co,point->loc); if(eff->pd->flag & PFIELD_TEX_2D) { float fac=-dot_v3v3(tex_co, efd->nor); @@ -878,11 +878,11 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected damp += wind_func(rng, noise_factor); } - VECCOPY(force, efd->vec_to_point); + copy_v3_v3(force, efd->vec_to_point); switch(pd->forcefield){ case PFIELD_WIND: - VECCOPY(force, efd->nor); + copy_v3_v3(force, efd->nor); mul_v3_fl(force, strength * efd->falloff); break; case PFIELD_FORCE: @@ -944,7 +944,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected return; case PFIELD_TURBULENCE: if(pd->flag & PFIELD_GLOBAL_CO) { - VECCOPY(temp, point->loc); + copy_v3_v3(temp, point->loc); } else { VECADD(temp, efd->vec_to_point2, efd->nor2); @@ -955,7 +955,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected mul_v3_fl(force, strength * efd->falloff); break; case PFIELD_DRAG: - VECCOPY(force, point->vel); + copy_v3_v3(force, point->vel); fac = normalize_v3(force) * point->vel_to_sec; strength = MIN2(strength, 2.0f); @@ -1039,7 +1039,7 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we do_texture_effector(eff, &efd, point, force); else { float temp1[3]={0,0,0}, temp2[3]; - VECCOPY(temp1, force); + copy_v3_v3(temp1, force); do_physical_effector(eff, &efd, point, force); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index aab8e1abbea..2a9e786d139 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1122,7 +1122,7 @@ int object_remove_material_slot(Object *ob) /* r g b = current value, col = new value, fac==0 is no change */ /* if g==NULL, it only does r channel */ -void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) +void ramp_blend(int type, float *r, float *g, float *b, float fac, const float col[3]) { float tmp, facm= 1.0f-fac; diff --git a/source/blender/blenkernel/intern/navmesh_conversion.cpp b/source/blender/blenkernel/intern/navmesh_conversion.cpp new file mode 100644 index 00000000000..cc3b926db75 --- /dev/null +++ b/source/blender/blenkernel/intern/navmesh_conversion.cpp @@ -0,0 +1,465 @@ +/** +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#include <math.h> +#include <stdlib.h> +#include "Recast.h" + +extern "C"{ +#include "BKE_navmesh_conversion.h" + +#include "DNA_meshdata_types.h" +#include "BKE_cdderivedmesh.h" +#include "BLI_math.h" +} + +inline float area2(const float* a, const float* b, const float* c) +{ + return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); +} + +inline bool left(const float* a, const float* b, const float* c) +{ + return area2(a, b, c) < 0; +} + +int polyNumVerts(const unsigned short* p, const int vertsPerPoly) +{ + int nv = 0; + for (int i=0; i<vertsPerPoly; i++) + { + if (p[i]==0xffff) + break; + nv++; + } + return nv; +} + +bool polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts) +{ + int nv = polyNumVerts(p, vertsPerPoly); + if (nv<3) + return false; + for (int j=0; j<nv; j++) + { + const float* v = &verts[3*p[j]]; + const float* v_next = &verts[3*p[(j+1)%nv]]; + const float* v_prev = &verts[3*p[(nv+j-1)%nv]]; + if (!left(v_prev, v, v_next)) + return false; + + } + return true; +} + +float distPointToSegmentSq(const float* point, const float* a, const float* b) +{ + float abx[3], dx[3]; + vsub(abx, b,a); + vsub(dx, point,a); + float d = abx[0]*abx[0]+abx[2]*abx[2]; + float t = abx[0]*dx[0]+abx[2]*dx[2]; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + dx[0] = a[0] + t*abx[0] - point[0]; + dx[2] = a[2] + t*abx[2] - point[2]; + return dx[0]*dx[0] + dx[2]*dx[2]; +} + +bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, + int &ntris, unsigned short *&tris, int *&trisToFacesMap, + int *&recastData) +{ + nverts = dm->getNumVerts(dm); + if (nverts>=0xffff) + { + printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff); + return false; + } + verts = new float[3*nverts]; + dm->getVertCos(dm, (float(*)[3])verts); + + //flip coordinates + for (int vi=0; vi<nverts; vi++) + { + SWAP(float, verts[3*vi+1], verts[3*vi+2]); + } + + //calculate number of tris + int nfaces = dm->getNumFaces(dm); + MFace *faces = dm->getFaceArray(dm); + ntris = nfaces; + for (int fi=0; fi<nfaces; fi++) + { + MFace* face = &faces[fi]; + if (face->v4) + ntris++; + } + + //copy and transform to triangles (reorder on the run) + trisToFacesMap = new int[ntris]; + tris = new unsigned short[3*ntris]; + unsigned short* tri = tris; + int triIdx = 0; + for (int fi=0; fi<nfaces; fi++) + { + MFace* face = &faces[fi]; + tri[3*triIdx+0] = (unsigned short) face->v1; + tri[3*triIdx+1] = (unsigned short) face->v3; + tri[3*triIdx+2] = (unsigned short) face->v2; + trisToFacesMap[triIdx++]=fi; + if (face->v4) + { + tri[3*triIdx+0] = (unsigned short) face->v1; + tri[3*triIdx+1] = (unsigned short) face->v4; + tri[3*triIdx+2] = (unsigned short) face->v3; + trisToFacesMap[triIdx++]=fi; + } + } + + //carefully, recast data is just reference to data in derived mesh + recastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); + return true; +} + +bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short* polys, const unsigned short* dmeshes, + const float* verts, const unsigned short* dtris, + const int* dtrisToPolysMap) +{ + int capacity = vertsPerPoly; + unsigned short* newPoly = new unsigned short[capacity]; + memset(newPoly, 0xff, sizeof(unsigned short)*capacity); + for (int polyidx=0; polyidx<npolys; polyidx++) + { + int nv = 0; + //search border + int btri = -1; + int bedge = -1; + int dtrisNum = dmeshes[polyidx*4+3]; + int dtrisBase = dmeshes[polyidx*4+2]; + unsigned char *traversedTris = new unsigned char[dtrisNum]; + memset(traversedTris, 0, dtrisNum*sizeof(unsigned char)); + for (int j=0; j<dtrisNum && btri==-1;j++) + { + int curpolytri = dtrisBase+j; + for (int k=0; k<3; k++) + { + unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; + if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) + { + btri = curpolytri; + bedge = k; + break; + } + } + } + if (btri==-1 || bedge==-1) + { + //can't find triangle with border edge + return false; + } + + newPoly[nv++] = dtris[btri*3*2+bedge]; + int tri = btri; + int edge = (bedge+1)%3; + traversedTris[tri-dtrisBase] = 1; + while (tri!=btri || edge!=bedge) + { + int neighbortri = dtris[tri*3*2+3+edge]; + if (neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) + { + if (nv==capacity) + { + capacity += vertsPerPoly; + unsigned short* newPolyBig = new unsigned short[capacity]; + memset(newPolyBig, 0xff, sizeof(unsigned short)*capacity); + memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv); + delete newPoly; + newPoly = newPolyBig; + } + newPoly[nv++] = dtris[tri*3*2+edge]; + //move to next edge + edge = (edge+1)%3; + } + else + { + //move to next tri + int twinedge = -1; + for (int k=0; k<3; k++) + { + if (dtris[neighbortri*3*2+3+k] == tri) + { + twinedge = k; + break; + } + } + if (twinedge==-1) + { + printf("Converting navmesh: Error! Can't find neighbor edge - invalid adjacency info\n"); + goto returnLabel; + } + tri = neighbortri; + edge = (twinedge+1)%3; + traversedTris[tri-dtrisBase] = 1; + } + } + + unsigned short* adjustedPoly = new unsigned short[nv]; + int adjustedNv = 0; + for (size_t i=0; i<(size_t)nv; i++) + { + unsigned short prev = newPoly[(nv+i-1)%nv]; + unsigned short cur = newPoly[i]; + unsigned short next = newPoly[(i+1)%nv]; + float distSq = distPointToSegmentSq(&verts[3*cur], &verts[3*prev], &verts[3*next]); + static const float tolerance = 0.001f; + if (distSq>tolerance) + adjustedPoly[adjustedNv++] = cur; + } + memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); + delete adjustedPoly; + nv = adjustedNv; + + bool allBorderTraversed = true; + for (size_t i=0; i<(size_t)dtrisNum; i++) + { + if (traversedTris[i]==0) + { + //check whether it has border edges + int curpolytri = dtrisBase+i; + for (int k=0; k<3; k++) + { + unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; + if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) + { + allBorderTraversed = false; + break; + } + } + } + } + + if (nv<=vertsPerPoly && allBorderTraversed) + { + for (int i=0; i<nv; i++) + { + polys[polyidx*vertsPerPoly*2+i] = newPoly[i]; + } + } + } + +returnLabel: + delete newPoly; + return true; +} + +struct SortContext +{ + const int* recastData; + const int* trisToFacesMap; +}; +#if defined(_MSC_VER) +static int compareByData(void* data, const void * a, const void * b) +#elif defined(__APPLE__) || defined(__FreeBSD__) +static int compareByData(void* data, const void * a, const void * b) +#else +static int compareByData(const void * a, const void * b, void* data) +#endif +{ + const SortContext* context = (const SortContext*)data; + return ( context->recastData[context->trisToFacesMap[*(int*)a]] - + context->recastData[context->trisToFacesMap[*(int*)b]] ); +} + +bool buildNavMeshData(const int nverts, const float* verts, + const int ntris, const unsigned short *tris, + const int* recastData, const int* trisToFacesMap, + int &ndtris, unsigned short *&dtris, + int &npolys, unsigned short *&dmeshes, unsigned short *&polys, + int &vertsPerPoly, int *&dtrisToPolysMap, int *&dtrisToTrisMap) + +{ + if (!recastData) + { + printf("Converting navmesh: Error! Can't find recast custom data\n"); + return false; + } + + //sort the triangles by polygon idx + int* trisMapping = new int[ntris]; + for (int i=0; i<ntris; i++) + trisMapping[i]=i; + SortContext context; + context.recastData = recastData; + context.trisToFacesMap = trisToFacesMap; +#if defined(_MSC_VER) + qsort_s(trisMapping, ntris, sizeof(int), compareByData, &context); +#elif defined(__APPLE__) || defined(__FreeBSD__) + qsort_r(trisMapping, ntris, sizeof(int), &context, compareByData); +#else + qsort_r(trisMapping, ntris, sizeof(int), compareByData, &context); +#endif + //search first valid triangle - triangle of convex polygon + int validTriStart = -1; + for (int i=0; i< ntris; i++) + { + if (recastData[trisToFacesMap[trisMapping[i]]]>0) + { + validTriStart = i; + break; + } + } + + if (validTriStart<0) + { + printf("Converting navmesh: Error! No valid polygons in mesh\n"); + delete trisMapping; + return false; + } + + ndtris = ntris-validTriStart; + //fill dtris to faces mapping + dtrisToTrisMap = new int[ndtris]; + memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); + delete trisMapping; trisMapping=NULL; + + //create detailed mesh triangles - copy only valid triangles + //and reserve memory for adjacency info + dtris = new unsigned short[3*2*ndtris]; + memset(dtris, 0xffff, sizeof(unsigned short)*3*2*ndtris); + for (int i=0; i<ndtris; i++) + { + memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3); + } + //create new recast data corresponded to dtris and renumber for continuous indices + int prevPolyIdx=-1, curPolyIdx, newPolyIdx=0; + dtrisToPolysMap = new int[ndtris]; + for (int i=0; i<ndtris; i++) + { + curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; + if (curPolyIdx!=prevPolyIdx) + { + newPolyIdx++; + prevPolyIdx=curPolyIdx; + } + dtrisToPolysMap[i] = newPolyIdx; + } + + + //build adjacency info for detailed mesh triangles + buildMeshAdjacency(dtris, ndtris, nverts, 3); + + //create detailed mesh description for each navigation polygon + npolys = dtrisToPolysMap[ndtris-1]; + dmeshes = new unsigned short[npolys*4]; + memset(dmeshes, 0, npolys*4*sizeof(unsigned short)); + unsigned short *dmesh = NULL; + int prevpolyidx = 0; + for (int i=0; i<ndtris; i++) + { + int curpolyidx = dtrisToPolysMap[i]; + if (curpolyidx!=prevpolyidx) + { + if (curpolyidx!=prevpolyidx+1) + { + printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n"); + return false; + } + dmesh = dmesh==NULL ? dmeshes : dmesh+4; + dmesh[2] = (unsigned short)i; //tbase + dmesh[3] = 0; //tnum + prevpolyidx = curpolyidx; + } + dmesh[3]++; + } + + //create navigation polygons + vertsPerPoly = 6; + polys = new unsigned short[npolys*vertsPerPoly*2]; + memset(polys, 0xff, sizeof(unsigned short)*vertsPerPoly*2*npolys); + + buildPolygonsByDetailedMeshes(vertsPerPoly, npolys, polys, dmeshes, verts, dtris, dtrisToPolysMap); + + return true; +} + + +bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly, + int &nverts, float *&verts, + int &ndtris, unsigned short *&dtris, + int& npolys, unsigned short *&dmeshes, + unsigned short*& polys, int *&dtrisToPolysMap, + int *&dtrisToTrisMap, int *&trisToFacesMap) +{ + bool res = true; + int ntris =0, *recastData=NULL; + unsigned short *tris=NULL; + res = buildRawVertIndicesData(dm, nverts, verts, ntris, tris, trisToFacesMap, recastData); + if (!res) + { + printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); + goto exit; + } + + res = buildNavMeshData(nverts, verts, ntris, tris, recastData, trisToFacesMap, + ndtris, dtris, npolys, dmeshes,polys, vertsPerPoly, + dtrisToPolysMap, dtrisToTrisMap); + if (!res) + { + printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); + goto exit; + } + +exit: + if (tris) + delete tris; + + return res; +} + +int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx) +{ + int res = -1; + for(int i=0; i<vertsPerPoly; i++) + { + if (p[i]==0xffff) + break; + if (p[i]==vertexIdx) + { + res = i; + break; + } + } + return res; +} diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 292f38b9472..d40b030c470 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -398,6 +398,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) sock->stack_index= 0; sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); + + /* XXX some compositor node (e.g. image, render layers) still store + * some persistent buffer data here, need to clear this to avoid dangling pointers. + */ + sock->cache = NULL; } BLI_duplicatelist(&nnode->outputs, &node->outputs); @@ -407,6 +412,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) sock->stack_index= 0; sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); + + /* XXX some compositor node (e.g. image, render layers) still store + * some persistent buffer data here, need to clear this to avoid dangling pointers. + */ + sock->cache = NULL; } /* don't increase node->id users, freenode doesn't decrement either */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0dc83084c90..898cec7fa55 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1082,6 +1082,7 @@ Object *add_only_object(int type, const char *name) ob->state=1; /* ob->pad3 == Contact Processing Threshold */ ob->m_contactProcessingThreshold = 1.; + ob->obstacleRad = 1.; /* NT fluid sim defaults */ ob->fluidsimFlag = 0; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 86c646fa257..60432631492 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2090,10 +2090,10 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) data = eff->guide_data + p; VECSUB(efd.vec_to_point, state.co, eff->guide_loc); - VECCOPY(efd.nor, eff->guide_dir); + copy_v3_v3(efd.nor, eff->guide_dir); efd.distance = len_v3(efd.vec_to_point); - VECCOPY(data->vec_to_point, efd.vec_to_point); + copy_v3_v3(data->vec_to_point, efd.vec_to_point); data->strength = effector_falloff(eff, &efd, &point, weights); } } diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 0d523599598..d529a6d94c9 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -396,6 +396,7 @@ void init_actuator(bActuator *act) bObjectActuator *oa; bRandomActuator *ra; bSoundActuator *sa; + bSteeringActuator *sta; if(act->data) MEM_freeN(act->data); act->data= NULL; @@ -470,6 +471,16 @@ void init_actuator(bActuator *act) case ACT_ARMATURE: act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act"); break; + case ACT_STEERING: + act->data = MEM_callocN(sizeof( bSteeringActuator), "steering act"); + sta = act->data; + sta->acceleration = 3.f; + sta->turnspeed = 120.f; + sta->dist = 1.f; + sta->velocity= 3.f; + sta->flag = ACT_STEERING_AUTOMATICFACING; + sta->facingaxis = 1; + break; default: ; /* this is very severe... I cannot make any memory for this */ /* logic brick... */ @@ -595,6 +606,11 @@ void set_sca_new_poins_ob(Object *ob) bPropertyActuator *pa= act->data; ID_NEW(pa->ob); } + else if(act->type==ACT_STEERING) { + bSteeringActuator *sta = act->data; + ID_NEW(sta->navmesh); + ID_NEW(sta->target); + } } act= act->next; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index d6003a44a7d..1454b3f0ce3 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -514,6 +514,23 @@ Scene *add_scene(const char *name) sce->gm.flag = GAME_DISPLAY_LISTS; sce->gm.matmode = GAME_MAT_MULTITEX; + sce->gm.obstacleSimulation= OBSTSIMULATION_NONE; + sce->gm.levelHeight = 2.f; + + sce->gm.recastData.cellsize = 0.3f; + sce->gm.recastData.cellheight = 0.2f; + sce->gm.recastData.agentmaxslope = M_PI/2; + sce->gm.recastData.agentmaxclimb = 0.9f; + sce->gm.recastData.agentheight = 2.0f; + sce->gm.recastData.agentradius = 0.6f; + sce->gm.recastData.edgemaxlen = 12.0f; + sce->gm.recastData.edgemaxerror = 1.3f; + sce->gm.recastData.regionminsize = 50.f; + sce->gm.recastData.regionmergesize = 20.f; + sce->gm.recastData.vertsperpoly = 6; + sce->gm.recastData.detailsampledist = 6.0f; + sce->gm.recastData.detailsamplemaxerror = 1.0f; + sound_create_scene(sce); return sce; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index dbb2e7860c5..a3237da6234 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1260,7 +1260,7 @@ static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int size_flags = seq->strip->proxy->build_size_flags; /* only use proxies, if they are enabled (even if present!) */ - if (psize != IMB_PROXY_NONE && ((size_flags & psize) != psize)) { + if (psize == IMB_PROXY_NONE || ((size_flags & psize) != psize)) { return NULL; } diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 7b04a72666d..d2d22aa213a 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -134,16 +134,6 @@ static void space_transform_invert_normal(const SpaceTransform *data, float *no) } /* - * Returns the squared distance between two given points - */ -static float squared_dist(const float *a, const float *b) -{ - float tmp[3]; - VECSUB(tmp, a, b); - return INPR(tmp, tmp); -} - -/* * Shrinkwrap to the nearest vertex * * it builds a kdtree of vertexs we can attach to and then @@ -195,7 +185,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) //so we can initiate the "nearest.dist" with the expected value to that last hit. //This will lead in prunning of the search tree. if(nearest.index != -1) - nearest.dist = squared_dist(tmp_co, nearest.co); + nearest.dist = len_squared_v3v3(tmp_co, nearest.co); else nearest.dist = FLT_MAX; @@ -328,7 +318,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) normalize_v3(proj_axis); //Invalid projection direction - if(INPR(proj_axis, proj_axis) < FLT_EPSILON) + if(dot_v3v3(proj_axis, proj_axis) < FLT_EPSILON) return; } @@ -469,7 +459,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) //so we can initiate the "nearest.dist" with the expected value to that last hit. //This will lead in prunning of the search tree. if(nearest.index != -1) - nearest.dist = squared_dist(tmp_co, nearest.co); + nearest.dist = len_squared_v3v3(tmp_co, nearest.co); else nearest.dist = FLT_MAX; diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c index 4cc5a880625..432dc9ec609 100644 --- a/source/blender/blenkernel/intern/sketch.c +++ b/source/blender/blenkernel/intern/sketch.c @@ -245,13 +245,13 @@ void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], f prev = stk->points + start; next = stk->points + end; - VECCOPY(pt1.p, p_start); - VECCOPY(pt1.no, prev->no); + copy_v3_v3(pt1.p, p_start); + copy_v3_v3(pt1.no, prev->no); pt1.mode = prev->mode; pt1.type = prev->type; - VECCOPY(pt2.p, p_end); - VECCOPY(pt2.no, next->no); + copy_v3_v3(pt2.p, p_end); + copy_v3_v3(pt2.no, next->no); pt2.mode = next->mode; pt2.type = next->type; @@ -323,7 +323,7 @@ void sk_flattenStroke(SK_Stroke *stk, int start, int end) total = end - start + 1; - VECCOPY(normal, stk->points[start].no); + copy_v3_v3(normal, stk->points[start].no); sub_v3_v3v3(distance, stk->points[end].p, stk->points[start].p); project_v3_v3v3(normal, distance, normal); diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h index 122b2679d5b..4309e6122df 100644 --- a/source/blender/blenlib/BLI_math_inline.h +++ b/source/blender/blenlib/BLI_math_inline.h @@ -45,8 +45,13 @@ extern "C" { #define MALWAYS_INLINE MINLINE #else #define MINLINE static inline +#if (defined(__APPLE__) && defined(__ppc__)) +/* static inline __attribute__ here breaks osx ppc gcc42 build */ +#define MALWAYS_INLINE static __attribute__((always_inline)) +#else #define MALWAYS_INLINE static inline __attribute__((always_inline)) #endif +#endif #else #define MINLINE #define MALWAYS_INLINE diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 18955c158c6..d6a8f0fb925 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -83,7 +83,7 @@ void mul_serie_m4(float R[4][4], float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]); void mul_m4_v3(float M[4][4], float r[3]); -void mul_v3_m4v3(float r[3], float M[4][4], float v[3]); +void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]); void mul_mat3_m4_v3(float M[4][4], float r[3]); void mul_m4_v4(float M[4][4], float r[4]); void mul_v4_m4v4(float r[4], float M[4][4], float v[4]); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index d30168c8657..a807a395b78 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -56,6 +56,12 @@ MINLINE void swap_v2_v2(float a[2], float b[2]); MINLINE void swap_v3_v3(float a[3], float b[3]); MINLINE void swap_v4_v4(float a[4], float b[4]); +/* short */ +MINLINE void copy_v2_v2_short(short r[2], const short a[2]); +MINLINE void copy_v3_v3_short(short r[3], const short a[3]); +MINLINE void copy_v4_v4_short(short r[4], const short a[4]); + + /********************************* Arithmetic ********************************/ MINLINE void add_v3_fl(float r[3], float f); diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 1a1f7be2471..9a3b81e5776 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -176,6 +176,12 @@ /* useful for debugging */ #define AT __FILE__ ":" STRINGIFY(__LINE__) +/* so we can use __func__ everywhere */ +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ +#endif + + /* UNUSED macro, for function argument */ #ifdef __GNUC__ # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index dcbe043f0d0..eae4f918a67 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -408,7 +408,7 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi // for all Axes. for (i = tree->start_axis; i < tree->stop_axis; i++) { - newminmax = INPR(&co[k * 3], KDOP_AXES[i]); + newminmax = dot_v3v3(&co[k * 3], KDOP_AXES[i]); if (newminmax < bv[2 * i]) bv[2 * i] = newminmax; if (newminmax > bv[(2 * i) + 1]) @@ -1193,17 +1193,6 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int return overlap; } - -/* - * Nearest neighbour - BLI_bvhtree_find_nearest - */ -static float squared_dist(const float *a, const float *b) -{ - float tmp[3]; - VECSUB(tmp, a, b); - return INPR(tmp, tmp); -} - //Determines the nearest point of the given node BV. Returns the squared distance to that point. static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest) { @@ -1226,7 +1215,7 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest VECCOPY(nearest, data->co); for(i = data->tree->start_axis; i != data->tree->stop_axis; i++, bv+=2) { - float proj = INPR( nearest, KDOP_AXES[i]); + float proj = dot_v3v3( nearest, KDOP_AXES[i]); float dl = bv[0] - proj; float du = bv[1] - proj; @@ -1240,7 +1229,7 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest } } */ - return squared_dist(proj, nearest); + return len_squared_v3v3(proj, nearest); } @@ -1404,7 +1393,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nea for(i = data.tree->start_axis; i != data.tree->stop_axis; i++) { - data.proj[i] = INPR(data.co, KDOP_AXES[i]); + data.proj[i] = dot_v3v3(data.co, KDOP_AXES[i]); } if(nearest) @@ -1596,7 +1585,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float for(i=0; i<3; i++) { - data.ray_dot_axis[i] = INPR( data.ray.direction, KDOP_AXES[i]); + data.ray_dot_axis[i] = dot_v3v3(data.ray.direction, KDOP_AXES[i]); data.idot_axis[i] = 1.0f / data.ray_dot_axis[i]; if(fabsf(data.ray_dot_axis[i]) < FLT_EPSILON) diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index 2e26f4bd9c9..8b9cddcc1d1 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -591,7 +591,7 @@ static void testRadialSymmetry(BGraph *graph, BNode* root_node, RadialArc* ring, node1 = BLI_otherNode(ring[i].arc, root_node); node2 = BLI_otherNode(ring[j].arc, root_node); - VECCOPY(p, node2->p); + copy_v3_v3(p, node2->p); BLI_mirrorAlongAxis(p, root_node->p, normal); /* check if it's within limit before continuing */ @@ -605,7 +605,7 @@ static void testRadialSymmetry(BGraph *graph, BNode* root_node, RadialArc* ring, if (symmetric) { /* mark node as symmetric physically */ - VECCOPY(root_node->symmetry_axis, axis); + copy_v3_v3(root_node->symmetry_axis, axis); root_node->symmetry_flag |= SYM_PHYSICAL; root_node->symmetry_flag |= SYM_RADIAL; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index e2f594376cb..20c503de2c3 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -306,7 +306,7 @@ void mul_serie_m4(float answ[][4], float m1[][4], } } -void mul_m4_v3(float mat[][4], float *vec) +void mul_m4_v3(float mat[][4], float vec[3]) { float x,y; @@ -317,7 +317,7 @@ void mul_m4_v3(float mat[][4], float *vec) vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; } -void mul_v3_m4v3(float *in, float mat[][4], float *vec) +void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) { float x,y; @@ -329,7 +329,7 @@ void mul_v3_m4v3(float *in, float mat[][4], float *vec) } /* same as mul_m4_v3() but doesnt apply translation component */ -void mul_mat3_m4_v3(float mat[][4], float *vec) +void mul_mat3_m4_v3(float mat[][4], float vec[3]) { float x,y; @@ -384,7 +384,7 @@ void mul_m3_v3(float M[3][3], float r[3]) copy_v3_v3(r, tmp); } -void mul_transposed_m3_v3(float mat[][3], float *vec) +void mul_transposed_m3_v3(float mat[][3], float vec[3]) { float x,y; @@ -422,7 +422,7 @@ void mul_mat3_m4_fl(float m[4][4], float f) m[i][j] *= f; } -void mul_m3_v3_double(float mat[][3], double *vec) +void mul_m3_v3_double(float mat[][3], double vec[3]) { double x,y; @@ -979,14 +979,14 @@ void size_to_mat4(float mat[][4], const float size[3]) copy_m4_m3(mat, tmat); } -void mat3_to_size(float *size, float mat[][3]) +void mat3_to_size(float size[3], float mat[][3]) { size[0]= len_v3(mat[0]); size[1]= len_v3(mat[1]); size[2]= len_v3(mat[2]); } -void mat4_to_size(float *size, float mat[][4]) +void mat4_to_size(float size[3], float mat[][4]) { size[0]= len_v3(mat[0]); size[1]= len_v3(mat[1]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 28708af7486..13623d9a93a 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -79,6 +79,28 @@ MINLINE void copy_v4_v4(float r[4], const float a[4]) r[3]= a[3]; } +/* short */ +MINLINE void copy_v2_v2_short(short r[2], const short a[2]) +{ + r[0]= a[0]; + r[1]= a[1]; +} + +MINLINE void copy_v3_v3_short(short r[3], const short a[3]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; +} + +MINLINE void copy_v4_v4_short(short r[4], const short a[4]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; + r[3]= a[3]; +} + MINLINE void swap_v2_v2(float a[2], float b[2]) { SWAP(float, a[0], b[0]); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index eb5d6a6fbcb..316999df6f6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3896,6 +3896,11 @@ static void lib_link_object(FileData *fd, Main *main) arma->target= newlibadr(fd, ob->id.lib, arma->target); arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget); } + else if(act->type==ACT_STEERING) { + bSteeringActuator *steeringa = act->data; + steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target); + steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh); + } act= act->next; } @@ -11615,6 +11620,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + // init facing axis property of steering actuators + { + Object *ob; + for(ob = main->object.first; ob; ob = ob->id.next) { + bActuator *act; + for(act= ob->actuators.first; act; act= act->next) { + if(act->type==ACT_STEERING) { + bSteeringActuator* stact = act->data; + if (stact->facingaxis==0) + { + stact->facingaxis=1; + } + } + } + } + } + if (main->versionfile < 256) { bScreen *sc; ScrArea *sa; @@ -12018,6 +12040,43 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } + //set defaults for obstacle avoidance, recast data + { + Scene *sce; + for(sce = main->scene.first; sce; sce = sce->id.next) + { + if (sce->gm.levelHeight == 0.f) + sce->gm.levelHeight = 2.f; + + if(sce->gm.recastData.cellsize == 0.0f) + sce->gm.recastData.cellsize = 0.3f; + if(sce->gm.recastData.cellheight == 0.0f) + sce->gm.recastData.cellheight = 0.2f; + if(sce->gm.recastData.agentmaxslope == 0.0f) + sce->gm.recastData.agentmaxslope = M_PI/4; + if(sce->gm.recastData.agentmaxclimb == 0.0f) + sce->gm.recastData.agentmaxclimb = 0.9f; + if(sce->gm.recastData.agentheight == 0.0f) + sce->gm.recastData.agentheight = 2.0f; + if(sce->gm.recastData.agentradius == 0.0f) + sce->gm.recastData.agentradius = 0.6f; + if(sce->gm.recastData.edgemaxlen == 0.0f) + sce->gm.recastData.edgemaxlen = 12.0f; + if(sce->gm.recastData.edgemaxerror == 0.0f) + sce->gm.recastData.edgemaxerror = 1.3f; + if(sce->gm.recastData.regionminsize == 0.0f) + sce->gm.recastData.regionminsize = 50.f; + if(sce->gm.recastData.regionmergesize == 0.0f) + sce->gm.recastData.regionmergesize = 20.f; + if(sce->gm.recastData.vertsperpoly<3) + sce->gm.recastData.vertsperpoly = 6; + if(sce->gm.recastData.detailsampledist == 0.0f) + sce->gm.recastData.detailsampledist = 6.0f; + if(sce->gm.recastData.detailsamplemaxerror == 0.0f) + sce->gm.recastData.detailsamplemaxerror = 1.0f; + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ @@ -12922,6 +12981,11 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) bArmatureActuator *arma= act->data; expand_doit(fd, mainvar, arma->target); } + else if(act->type==ACT_STEERING) { + bSteeringActuator *sta= act->data; + expand_doit(fd, mainvar, sta->target); + expand_doit(fd, mainvar, sta->navmesh); + } act= act->next; } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 3b736e8aeae..e92ec5dbe6e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1146,6 +1146,9 @@ static void write_actuators(WriteData *wd, ListBase *lb) case ACT_ARMATURE: writestruct(wd, DATA, "bArmatureActuator", 1, act->data); break; + case ACT_STEERING: + writestruct(wd, DATA, "bSteeringActuator", 1, act->data); + break; default: ; /* error: don't know how to write this file */ } diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index 498ccb5709d..2ea10111bb9 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -58,7 +58,7 @@ void AnimationExporter::operator() (Object *ob) { FCurve *fcu; char * transformName ; - bool isMatAnim = false; + /* bool isMatAnim = false; */ /* UNUSED */ //Export transform animations if(ob->adt && ob->adt->action) @@ -125,7 +125,7 @@ void AnimationExporter::operator() (Object *ob) if (!ma) continue; if(ma->adt && ma->adt->action) { - isMatAnim = true; + /* isMatAnim = true; */ fcu = (FCurve*)ma->adt->action->curves.first; while (fcu) { transformName = extract_transform_name( fcu->rna_path ); diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index de01c000373..431c67833f1 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -49,7 +49,7 @@ // XXX exporter writes wrong data for shared armatures. A separate // controller should be written for each armature-mesh binding how do // we make controller ids then? -ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryControllers(sw) {} +ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {} // write bone nodes void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce) @@ -90,14 +90,14 @@ void ArmatureExporter::add_instance_controller(Object *ob) ins.add(); } -void ArmatureExporter::export_controllers(Scene *sce, bool export_selected) +void ArmatureExporter::export_controllers(Scene *sce) { scene = sce; openLibrary(); GeometryFunctor gf; - gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, export_selected); + gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, this->export_settings->selected); closeLibrary(); } diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index b3441c797e8..554a8a7cfe6 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -47,16 +47,15 @@ #include "TransformWriter.h" #include "InstanceWriter.h" +#include "ExportSettings.h" + // XXX exporter writes wrong data for shared armatures. A separate // controller should be written for each armature-mesh binding how do // we make controller ids then? class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter { -private: - Scene *scene; - public: - ArmatureExporter(COLLADASW::StreamWriter *sw); + ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); // write bone nodes void add_armature_bones(Object *ob_arm, Scene *sce); @@ -65,13 +64,14 @@ public: void add_instance_controller(Object *ob); - void export_controllers(Scene *sce, bool export_selected); + void export_controllers(Scene *sce); void operator()(Object *ob); private: - + Scene *scene; UnitConverter converter; + const ExportSettings *export_settings; #if 0 std::vector<Object*> written_armatures; @@ -119,25 +119,4 @@ private: Object *ob_arm, ListBase *defbase); }; -/* -struct GeometryFunctor { - // f should have - // void operator()(Object* ob) - template<class Functor> - void forEachMeshObjectInScene(Scene *sce, Functor &f) - { - - Base *base= (Base*) sce->base.first; - while(base) { - Object *ob = base->object; - - if (ob->type == OB_MESH && ob->data) { - f(ob); - } - base= base->next; - - } - } -};*/ - #endif diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 19fa54c5044..ae25d343d36 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -576,7 +576,7 @@ void ArmatureImporter::set_pose ( Object * ob_arm , COLLADAFW::Node * root_node float obmat[4][4]; float ax[3]; - float angle = NULL; + float angle = 0.0f; // object-space get_node_mat(obmat, root_node, NULL, NULL); diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt index cc7229383e3..2ee34091fc9 100644 --- a/source/blender/collada/CMakeLists.txt +++ b/source/blender/collada/CMakeLists.txt @@ -52,6 +52,7 @@ set(SRC DocumentImporter.cpp EffectExporter.cpp ErrorHandler.cpp + ExportSettings.cpp ExtraHandler.cpp ExtraTags.cpp GeometryExporter.cpp @@ -77,6 +78,7 @@ set(SRC DocumentImporter.h EffectExporter.h ErrorHandler.h + ExportSettings.h ExtraHandler.h ExtraTags.h GeometryExporter.h diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index a935f45c403..542409072f1 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -39,7 +39,7 @@ #include "collada_internal.h" -CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryCameras(sw){} +CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryCameras(sw), export_settings(export_settings) {} template<class Functor> void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected) @@ -56,11 +56,11 @@ void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected) } } -void CamerasExporter::exportCameras(Scene *sce, bool export_selected) +void CamerasExporter::exportCameras(Scene *sce) { openLibrary(); - forEachCameraObjectInScene(sce, *this, export_selected); + forEachCameraObjectInScene(sce, *this, this->export_settings->selected); closeLibrary(); } diff --git a/source/blender/collada/CameraExporter.h b/source/blender/collada/CameraExporter.h index 999a6ddd3e5..8d08fe23f80 100644 --- a/source/blender/collada/CameraExporter.h +++ b/source/blender/collada/CameraExporter.h @@ -36,12 +36,16 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "ExportSettings.h" + class CamerasExporter: COLLADASW::LibraryCameras { public: - CamerasExporter(COLLADASW::StreamWriter *sw); - void exportCameras(Scene *sce, bool export_selected); + CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + void exportCameras(Scene *sce); void operator()(Object *ob, Scene *sce); +private: + const ExportSettings *export_settings; }; #endif diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 85f37d29f22..d562e51b922 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -110,6 +110,7 @@ extern char build_rev[]; #include "collada_internal.h" #include "DocumentExporter.h" +#include "ExportSettings.h" // can probably go after refactor is complete #include "InstanceWriter.h" @@ -145,11 +146,13 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) return data->layers[layer_index].name; } +DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {} + // TODO: it would be better to instantiate animations rather than create a new one per object // COLLADA allows this through multiple <channel>s in <animation>. // For this to work, we need to know objects that use a certain action. -void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool selected) +void DocumentExporter::exportCurrentScene(Scene *sce) { PointerRNA sceneptr, unit_settings; PropertyRNA *system; /* unused , *scale; */ @@ -157,7 +160,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool clear_global_id_map(); COLLADABU::NativeString native_filename = - COLLADABU::NativeString(std::string(filename)); + COLLADABU::NativeString(std::string(this->export_settings->filepath)); COLLADASW::StreamWriter sw(native_filename); // open <collada> @@ -227,32 +230,32 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool // <library_cameras> if(has_object_type(sce, OB_CAMERA)) { - CamerasExporter ce(&sw); - ce.exportCameras(sce, selected); + CamerasExporter ce(&sw, this->export_settings); + ce.exportCameras(sce); } // <library_lights> if(has_object_type(sce, OB_LAMP)) { - LightsExporter le(&sw); - le.exportLights(sce, selected); + LightsExporter le(&sw, this->export_settings); + le.exportLights(sce); } // <library_images> - ImagesExporter ie(&sw, filename); - ie.exportImages(sce, selected); + ImagesExporter ie(&sw, this->export_settings); + ie.exportImages(sce); // <library_effects> - EffectsExporter ee(&sw); - ee.exportEffects(sce, selected); + EffectsExporter ee(&sw, this->export_settings); + ee.exportEffects(sce); // <library_materials> - MaterialsExporter me(&sw); - me.exportMaterials(sce, selected); + MaterialsExporter me(&sw, this->export_settings); + me.exportMaterials(sce); // <library_geometries> if(has_object_type(sce, OB_MESH)) { - GeometryExporter ge(&sw); - ge.exportGeom(sce, selected); + GeometryExporter ge(&sw, this->export_settings); + ge.exportGeom(sce); } // <library_animations> @@ -260,14 +263,14 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool ae.exportAnimations(sce); // <library_controllers> - ArmatureExporter arm_exporter(&sw); + ArmatureExporter arm_exporter(&sw, this->export_settings); if(has_object_type(sce, OB_ARMATURE)) { - arm_exporter.export_controllers(sce, selected); + arm_exporter.export_controllers(sce); } // <library_visual_scenes> - SceneExporter se(&sw, &arm_exporter); - se.exportScene(sce, selected); + SceneExporter se(&sw, &arm_exporter, this->export_settings); + se.exportScene(sce); // <scene> std::string scene_name(translate_id(id_name(sce))); diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h index 923313c4ed9..83724505efa 100644 --- a/source/blender/collada/DocumentExporter.h +++ b/source/blender/collada/DocumentExporter.h @@ -29,13 +29,18 @@ #ifndef __DOCUMENTEXPORTER_H__ #define __DOCUMENTEXPORTER_H__ +#include "ExportSettings.h" + struct Scene; class DocumentExporter { public: - void exportCurrentScene(Scene *sce, const char* filename, bool selected); + DocumentExporter(const ExportSettings *export_settings); + void exportCurrentScene(Scene *sce); void exportScenes(const char* filename); +private: + const ExportSettings *export_settings; }; #endif diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 355e384d000..6863e26a3ce 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -37,6 +37,7 @@ #include "DNA_mesh_types.h" #include "DNA_texture_types.h" +#include "DNA_world_types.h" #include "BKE_customdata.h" @@ -55,7 +56,7 @@ static std::string getActiveUVLayerName(Object *ob) return ""; } -EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryEffects(sw){} +EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {} bool EffectsExporter::hasEffects(Scene *sce) { @@ -78,12 +79,13 @@ bool EffectsExporter::hasEffects(Scene *sce) return false; } -void EffectsExporter::exportEffects(Scene *sce, bool export_selected) +void EffectsExporter::exportEffects(Scene *sce) { if(hasEffects(sce)) { + this->scene = sce; openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInScene<EffectsExporter>(sce, *this, export_selected); + mf.forEachMaterialInScene<EffectsExporter>(sce, *this, this->export_settings->selected); closeLibrary(); } @@ -175,7 +177,12 @@ void EffectsExporter::operator()(Material *ma, Object *ob) ep.setDiffuse(cot, false , "diffuse"); // ambient - cot = getcol(ma->ambr, ma->ambg, ma->ambb, 1.0f); + /* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */ + if(this->scene->world) + cot = getcol(this->scene->world->ambr*ma->amb, this->scene->world->ambg*ma->amb, this->scene->world->ambb*ma->amb, 1.0f); + else + cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f); + ep.setAmbient(cot, false , "ambient"); // reflective, reflectivity diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h index 86143ae4d07..25d7ed15bc3 100644 --- a/source/blender/collada/EffectExporter.h +++ b/source/blender/collada/EffectExporter.h @@ -43,11 +43,13 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "ExportSettings.h" + class EffectsExporter: COLLADASW::LibraryEffects { public: - EffectsExporter(COLLADASW::StreamWriter *sw); - void exportEffects(Scene *sce, bool export_selected); + EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + void exportEffects(Scene *sce); void operator()(Material *ma, Object *ob); @@ -66,6 +68,10 @@ private: void writePhong(COLLADASW::EffectProfile &ep, Material *ma); bool hasEffects(Scene *sce); + + const ExportSettings *export_settings; + + Scene *scene; }; #endif diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp index 7108dbad18a..61c03ed673c 100644 --- a/source/blender/collada/ErrorHandler.cpp +++ b/source/blender/collada/ErrorHandler.cpp @@ -49,6 +49,8 @@ ErrorHandler::~ErrorHandler() //-------------------------------------------------------------------- bool ErrorHandler::handleError( const COLLADASaxFWL::IError* error ) { + mError = true; + if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER ) { COLLADASaxFWL::SaxParserError* saxParserError = (COLLADASaxFWL::SaxParserError*) error; @@ -59,32 +61,29 @@ bool ErrorHandler::handleError( const COLLADASaxFWL::IError* error ) { if ( strcmp(parserError.getElement(), "effect") == 0 ) { - return false; + mError = false; } } if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) { - if ( (strcmp(parserError.getElement(), "extra") == 0) - && (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0)) + if ( !((strcmp(parserError.getElement(), "extra") == 0) + && (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0))) { - return false; + mError = false; } } if ( parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) { std::cout << "Couldn't open file" << std::endl; - mError = true; } std::cout << "Schema validation error: " << parserError.getErrorMessage() << std::endl; - mError = true; } else if ( error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL ) { COLLADASaxFWL::SaxFWLError* saxFWLError = (COLLADASaxFWL::SaxFWLError*) error; std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl; - mError = true; } return false; } diff --git a/source/blender/collada/ExportSettings.cpp b/source/blender/collada/ExportSettings.cpp new file mode 100644 index 00000000000..19f1c05ddcf --- /dev/null +++ b/source/blender/collada/ExportSettings.cpp @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/collada/ExportSettings.cpp + * \ingroup collada + */ + +#include "ExportSettings.h" diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h new file mode 100644 index 00000000000..2636ca88a23 --- /dev/null +++ b/source/blender/collada/ExportSettings.h @@ -0,0 +1,39 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file ExportSettings.h + * \ingroup collada + */ + +#ifndef __EXPORTSETTINGS_H__ +#define __EXPORTSETTINGS_H__ + +struct ExportSettings +{ + public: + bool selected; + char *filepath; +}; + +#endif diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index b724844b1ec..4da0a4c6e1f 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -44,16 +44,16 @@ #include "collada_internal.h" // TODO: optimize UV sets by making indexed list with duplicates removed -GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryGeometries(sw) {} +GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {} -void GeometryExporter::exportGeom(Scene *sce, bool export_selected) +void GeometryExporter::exportGeom(Scene *sce) { openLibrary(); mScene = sce; GeometryFunctor gf; - gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, export_selected); + gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, this->export_settings->selected); closeLibrary(); } diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index d9d265a66fc..64c51b6324e 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -42,6 +42,8 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "ExportSettings.h" + // TODO: optimize UV sets by making indexed list with duplicates removed class GeometryExporter : COLLADASW::LibraryGeometries { @@ -58,9 +60,9 @@ class GeometryExporter : COLLADASW::LibraryGeometries Scene *mScene; public: - GeometryExporter(COLLADASW::StreamWriter *sw); + GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); - void exportGeom(Scene *sce, bool export_selected); + void exportGeom(Scene *sce); void operator()(Object *ob); @@ -96,6 +98,8 @@ public: /* int getTriCount(MFace *faces, int totface);*/ private: std::set<std::string> exportedGeometry; + + const ExportSettings *export_settings; }; struct GeometryFunctor { diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index 8e426e9dba8..747f3c783d7 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -43,7 +43,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" -ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename) : COLLADASW::LibraryImages(sw), mfilename(filename) +ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryImages(sw), export_settings(export_settings) {} bool ImagesExporter::hasImages(Scene *sce) @@ -71,12 +71,12 @@ bool ImagesExporter::hasImages(Scene *sce) return false; } -void ImagesExporter::exportImages(Scene *sce, bool export_selected) +void ImagesExporter::exportImages(Scene *sce) { if(hasImages(sce)) { openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInScene<ImagesExporter>(sce, *this, export_selected); + mf.forEachMaterialInScene<ImagesExporter>(sce, *this, this->export_settings->selected); closeLibrary(); } @@ -97,7 +97,7 @@ void ImagesExporter::operator()(Material *ma, Object *ob) char src[FILE_MAX]; char dir[FILE_MAX]; - BLI_split_dirfile(mfilename, dir, NULL); + BLI_split_dirfile(this->export_settings->filepath, dir, NULL); BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.main->name, image->name, dir); diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h index 6b81c099259..9e5767fd9d3 100644 --- a/source/blender/collada/ImageExporter.h +++ b/source/blender/collada/ImageExporter.h @@ -40,17 +40,19 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "ExportSettings.h" + class ImagesExporter: COLLADASW::LibraryImages { - const char *mfilename; - std::vector<std::string> mImages; // contains list of written images, to avoid duplicates public: - ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename); + ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); - void exportImages(Scene *sce, bool export_selected); + void exportImages(Scene *sce); void operator()(Material *ma, Object *ob); private: + std::vector<std::string> mImages; // contains list of written images, to avoid duplicates bool hasImages(Scene *sce); + const ExportSettings *export_settings; }; #endif diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp index 31ade5604a7..3d5814cb6db 100644 --- a/source/blender/collada/LightExporter.cpp +++ b/source/blender/collada/LightExporter.cpp @@ -52,13 +52,13 @@ void forEachLampObjectInScene(Scene *sce, Functor &f, bool export_selected) } } -LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryLights(sw){} +LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryLights(sw), export_settings(export_settings) {} -void LightsExporter::exportLights(Scene *sce, bool export_selected) +void LightsExporter::exportLights(Scene *sce) { openLibrary(); - forEachLampObjectInScene(sce, *this, export_selected); + forEachLampObjectInScene(sce, *this, this->export_settings->selected); closeLibrary(); } diff --git a/source/blender/collada/LightExporter.h b/source/blender/collada/LightExporter.h index 2ae1a19fdb1..6c52ed2b76d 100644 --- a/source/blender/collada/LightExporter.h +++ b/source/blender/collada/LightExporter.h @@ -37,14 +37,17 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "ExportSettings.h" + class LightsExporter: COLLADASW::LibraryLights { public: - LightsExporter(COLLADASW::StreamWriter *sw); - void exportLights(Scene *sce, bool export_selected); + LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + void exportLights(Scene *sce); void operator()(Object *ob); private: bool exportBlenderProfile(COLLADASW::Light &cla, Lamp *la); + const ExportSettings *export_settings; }; #endif diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index 9d29177578d..37c1a6f6b68 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -33,15 +33,15 @@ #include "COLLADABUUtils.h" #include "collada_internal.h" -MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryMaterials(sw){} +MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryMaterials(sw), export_settings(export_settings) {} -void MaterialsExporter::exportMaterials(Scene *sce, bool export_selected) +void MaterialsExporter::exportMaterials(Scene *sce) { if(hasMaterials(sce)) { openLibrary(); MaterialFunctor mf; - mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected); + mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, this->export_settings->selected); closeLibrary(); } diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h index c080e4b0596..97a1e27358f 100644 --- a/source/blender/collada/MaterialExporter.h +++ b/source/blender/collada/MaterialExporter.h @@ -44,16 +44,18 @@ #include "GeometryExporter.h" #include "collada_internal.h" +#include "ExportSettings.h" class MaterialsExporter: COLLADASW::LibraryMaterials { public: - MaterialsExporter(COLLADASW::StreamWriter *sw); - void exportMaterials(Scene *sce, bool export_selected); + MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); + void exportMaterials(Scene *sce); void operator()(Material *ma, Object *ob); private: bool hasMaterials(Scene *sce); + const ExportSettings *export_settings; }; // used in forEachMaterialInScene diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 96f20ac21c3..a561d18c6e3 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -28,21 +28,21 @@ #include "SceneExporter.h" -SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm) - : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm) +SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings) + : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings) {} -void SceneExporter::exportScene(Scene *sce, bool export_selected) +void SceneExporter::exportScene(Scene *sce) { // <library_visual_scenes> <visual_scene> std::string id_naming = id_name(sce); openVisualScene(translate_id(id_naming), id_naming); - exportHierarchy(sce, export_selected); + exportHierarchy(sce); closeVisualScene(); closeLibrary(); } -void SceneExporter::exportHierarchy(Scene *sce, bool export_selected) +void SceneExporter::exportHierarchy(Scene *sce) { Base *base= (Base*) sce->base.first; while(base) { @@ -56,7 +56,7 @@ void SceneExporter::exportHierarchy(Scene *sce, bool export_selected) case OB_LAMP: case OB_ARMATURE: case OB_EMPTY: - if (export_selected && !(ob->flag & SELECT)) { + if (this->export_settings->selected && !(ob->flag & SELECT)) { break; } // write nodes.... @@ -126,7 +126,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) if((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) { GroupObject *go = NULL; Group *gr = ob->dup_group; - printf("group detected %u\n", gr); + /* printf("group detected '%s'\n", gr->id.name+2); */ for(go = (GroupObject*)(gr->gobject.first); go; go=go->next) { printf("\t%s\n", go->ob->id.name); } diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h index 65dbd616b20..919cba61ec0 100644 --- a/source/blender/collada/SceneExporter.h +++ b/source/blender/collada/SceneExporter.h @@ -90,16 +90,20 @@ extern "C" { #include "ArmatureExporter.h" +#include "ExportSettings.h" + class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter { - ArmatureExporter *arm_exporter; public: - SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm); - void exportScene(Scene *sce, bool export_selected); + SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings); + void exportScene(Scene *sce); private: - void exportHierarchy(Scene *sce, bool export_selected); + void exportHierarchy(Scene *sce); void writeNodes(Object *ob, Scene *sce); + + ArmatureExporter *arm_exporter; + const ExportSettings *export_settings; }; #endif diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 4caca20531f..8059b1cf3ff 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -30,6 +30,7 @@ /* COLLADABU_ASSERT, may be able to remove later */ #include "COLLADABUPlatform.h" +#include "ExportSettings.h" #include "DocumentExporter.h" #include "DocumentImporter.h" @@ -53,7 +54,10 @@ extern "C" int collada_export(Scene *sce, const char *filepath, int selected) { - DocumentExporter exp; + ExportSettings export_settings; + + export_settings.selected = selected != 0; + export_settings.filepath = (char *)filepath; /* annoying, collada crashes if file cant be created! [#27162] */ if(!BLI_exist(filepath)) { @@ -64,7 +68,8 @@ extern "C" } /* end! */ - exp.exportCurrentScene(sce, filepath, selected); + DocumentExporter exporter(&export_settings); + exporter.exportCurrentScene(sce); return 1; } diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index bdc654ff25a..276765bf96e 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -121,7 +121,7 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox((expanded)? (1):(1|8)); + uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8); } @@ -401,7 +401,7 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi * - top and bottom * - special hack: make the top a bit higher, since we are first... */ - uiSetRoundBox((1|8)); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); uiDrawBox(GL_POLYGON, 0, yminc-2, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8); } @@ -756,7 +756,7 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox((expanded)? (1):(1|8)); + uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8); } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 53c9fc4d82c..1e7c18dc6ac 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -531,7 +531,7 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop) bConstraint *con= NULL; short searchtype= VISUALKEY_NONE; short has_parent = FALSE; - char *identifier= NULL; + const char *identifier= NULL; /* validate data */ // TODO: this check is probably not needed, but it won't hurt @@ -548,7 +548,7 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop) Object *ob= (Object *)ptr->data; con= ob->constraints.first; - identifier= (char *)RNA_property_identifier(prop); + identifier= RNA_property_identifier(prop); has_parent= (ob->parent != NULL); } else if (ptr->type == &RNA_PoseBone) { @@ -556,7 +556,7 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop) bPoseChannel *pchan= (bPoseChannel *)ptr->data; con= pchan->constraints.first; - identifier= (char *)RNA_property_identifier(prop); + identifier= RNA_property_identifier(prop); has_parent= (pchan->parent != NULL); } @@ -565,12 +565,18 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop) return 0; /* location or rotation identifiers only... */ - if (strstr(identifier, "location")) + if(identifier == NULL) { + printf("%s failed: NULL identifier\n", __func__); + return 0; + } + else if (strstr(identifier, "location")) { searchtype= VISUALKEY_LOC; - else if (strstr(identifier, "rotation")) + } + else if (strstr(identifier, "rotation")) { searchtype= VISUALKEY_ROT; + } else { - printf("visualkey_can_use() failed: identifier - '%s' \n", identifier); + printf("%s failed: identifier - '%s' \n", __func__, identifier); return 0; } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 97f85b92b32..bcd9d746a44 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -409,10 +409,10 @@ static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3]) ReebNode *node; node = MEM_callocN(sizeof(ReebNode), "reeb node"); - VECCOPY(node->p, pt->p); + copy_v3_v3(node->p, pt->p); mul_m4_v3(imat, node->p); - VECCOPY(node->no, pt->no); + copy_v3_v3(node->no, pt->no); mul_m3_v3(tmat, node->no); return node; @@ -432,10 +432,10 @@ static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3]) for (i = 0; i < arc->bcount; i++) { - VECCOPY(arc->buckets[i].p, stk->points[i + 1].p); + copy_v3_v3(arc->buckets[i].p, stk->points[i + 1].p); mul_m4_v3(imat, arc->buckets[i].p); - VECCOPY(arc->buckets[i].no, stk->points[i + 1].no); + copy_v3_v3(arc->buckets[i].no, stk->points[i + 1].no); mul_m3_v3(tmat, arc->buckets[i].no); } @@ -1802,8 +1802,8 @@ void sk_applyCutGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSED pt.type = PT_EXACT; pt.mode = PT_PROJECT; /* take mode from neighbouring points */ - VECCOPY(pt.p, isect->p); - VECCOPY(pt.no, isect->stroke->points[isect->before].no); + copy_v3_v3(pt.p, isect->p); + copy_v3_v3(pt.no, isect->stroke->points[isect->before].no); sk_insertStrokePoint(isect->stroke, &pt, isect->after); } @@ -1844,8 +1844,8 @@ void sk_applyTrimGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UNUSE pt.type = PT_EXACT; pt.mode = PT_PROJECT; /* take mode from neighbouring points */ - VECCOPY(pt.p, isect->p); - VECCOPY(pt.no, isect->stroke->points[isect->before].no); + copy_v3_v3(pt.p, isect->p); + copy_v3_v3(pt.no, isect->stroke->points[isect->before].no); sub_v3_v3v3(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p); diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 0c2f8ca2ed4..127b2f4e663 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -518,7 +518,7 @@ static float heat_source_distance(LaplacianSystem *sys, int vertex, int source) dist= normalize_v3(d); /* if the vertex normal does not point along the bone, increase distance */ - cosine= INPR(d, sys->heat.vnors[vertex]); + cosine= dot_v3v3(d, sys->heat.vnors[vertex]); return dist/(0.5f*(cosine + 1.001f)); } @@ -1124,7 +1124,7 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], cross_v3_v3v3(pvec, dir, edge2); /* if determinant is near zero, ray lies in plane of triangle */ - det = INPR(edge1, pvec); + det = dot_v3v3(edge1, pvec); if (det == 0.0f) return 0; @@ -1134,7 +1134,7 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], sub_v3_v3v3(tvec, orig, vert0); /* calculate U parameter and test bounds */ - u = INPR(tvec, pvec) * inv_det; + u = dot_v3v3(tvec, pvec) * inv_det; if (u < -EPSILON || u > 1.0f+EPSILON) return 0; @@ -1142,7 +1142,7 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], cross_v3_v3v3(qvec, tvec, edge1); /* calculate V parameter and test bounds */ - v = INPR(dir, qvec) * inv_det; + v = dot_v3v3(dir, qvec) * inv_det; if (v < -EPSILON || u + v > 1.0f+EPSILON) return 0; @@ -1157,10 +1157,10 @@ static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3], /* check if it is within the length of the line segment */ sub_v3_v3v3(isectdir, isectco, orig); - if(INPR(dir, isectdir) < -EPSILON) + if(dot_v3v3(dir, isectdir) < -EPSILON) return 0; - if(INPR(dir, dir) + EPSILON < INPR(isectdir, isectdir)) + if(dot_v3v3(dir, dir) + EPSILON < dot_v3v3(isectdir, isectdir)) return 0; return 1; @@ -1206,7 +1206,7 @@ static int meshdeform_intersect(MeshDeformBind *mdb, MeshDeformIsect *isec) if(len < isec->labda) { isec->labda= len; isec->face = mface; - isec->isect= (INPR(isec->vec, nor) <= 0.0f); + isec->isect= (dot_v3v3(isec->vec, nor) <= 0.0f); is= 1; } } diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index c646ec55506..b451e278d47 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -136,8 +136,8 @@ void ED_setflagsLatt(struct Object *obedit, int flag); /* object_modifier.c */ enum { MODIFIER_APPLY_DATA=1, - MODIFIER_APPLY_SHAPE, -} eModifier_Apply_Mode; + MODIFIER_APPLY_SHAPE +}; struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, const char *name, int type); int ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct ModifierData *md); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 3fe012ea73e..637940f59a6 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -653,6 +653,25 @@ void UI_exit(void); #define UI_LAYOUT_OP_SHOW_TITLE 1 #define UI_LAYOUT_OP_SHOW_EMPTY 2 +/* flags to set which corners will become rounded: + * + * 1------2 + * | | + * 8------4 */ + +enum { + UI_CNR_TOP_LEFT= 1, + UI_CNR_TOP_RIGHT= 2, + UI_CNR_BOTTOM_RIGHT= 4, + UI_CNR_BOTTOM_LEFT= 8, + /* just for convenience */ + UI_CNR_NONE= 0, + UI_CNR_ALL= (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT) +}; + +/* not apart of the corner flags but mixed in some functions */ +#define UI_RB_ALPHA (UI_CNR_ALL + 1) + uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style); void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout); void uiBlockLayoutResolve(uiBlock *block, int *x, int *y); diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index d383bc0ab78..ab5b8e8aff3 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -296,6 +296,9 @@ void UI_GetThemeColorType4ubv(int colorid, int spacetype, char col[4]); // blends and shades between two color pointers void UI_ColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], float fac, int offset); +// shade a 3 byte color (same as UI_GetColorPtrBlendShade3ubv with 0.0 factor) +void UI_GetColorPtrShade3ubv(const unsigned char cp1[3], unsigned char col[3], int offset); + // get a 3 byte color, blended and shaded between two other char color pointers void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3], float fac, int offset); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 2267f04aab4..33aeb2df926 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -58,10 +58,9 @@ /* own include */ #include "interface_intern.h" -#define UI_RB_ALPHA 16 #define UI_DISABLED_ALPHA_OFFS -160 -static int roundboxtype= 15; +static int roundboxtype= UI_CNR_ALL; void uiSetRoundBox(int type) { @@ -69,13 +68,6 @@ void uiSetRoundBox(int type) * if this is undone, its not that big a deal, only makes curves edges * square for the */ roundboxtype= type; - - /* flags to set which corners will become rounded: - - 1------2 - | | - 8------4 - */ } @@ -98,7 +90,7 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r glBegin(mode); /* start with corner right-bottom */ - if(roundboxtype & 4) { + if(roundboxtype & UI_CNR_BOTTOM_RIGHT) { glVertex2f(maxx-rad, miny); for(a=0; a<7; a++) { glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]); @@ -108,7 +100,7 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r else glVertex2f(maxx, miny); /* corner right-top */ - if(roundboxtype & 2) { + if(roundboxtype & UI_CNR_TOP_RIGHT) { glVertex2f(maxx, maxy-rad); for(a=0; a<7; a++) { glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]); @@ -118,7 +110,7 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r else glVertex2f(maxx, maxy); /* corner left-top */ - if(roundboxtype & 1) { + if(roundboxtype & UI_CNR_TOP_LEFT) { glVertex2f(minx+rad, maxy); for(a=0; a<7; a++) { glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]); @@ -128,7 +120,7 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r else glVertex2f(minx, maxy); /* corner left-bottom */ - if(roundboxtype & 8) { + if(roundboxtype & UI_CNR_BOTTOM_LEFT) { glVertex2f(minx, miny+rad); for(a=0; a<7; a++) { glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]); @@ -180,7 +172,7 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl glBegin(mode); /* start with corner right-bottom */ - if(roundboxtype & 4) { + if(roundboxtype & UI_CNR_BOTTOM_RIGHT) { round_box_shade_col(coltop, coldown, 0.0); glVertex2f(maxx-rad, miny); @@ -199,7 +191,7 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl } /* corner right-top */ - if(roundboxtype & 2) { + if(roundboxtype & UI_CNR_TOP_RIGHT) { round_box_shade_col(coltop, coldown, (div-rad)*idiv); glVertex2f(maxx, maxy-rad); @@ -217,7 +209,7 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl } /* corner left-top */ - if(roundboxtype & 1) { + if(roundboxtype & UI_CNR_TOP_LEFT) { round_box_shade_col(coltop, coldown, 1.0); glVertex2f(minx+rad, maxy); @@ -236,7 +228,7 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl } /* corner left-bottom */ - if(roundboxtype & 8) { + if(roundboxtype & UI_CNR_BOTTOM_LEFT) { round_box_shade_col(coltop, coldown, rad*idiv); glVertex2f(minx, miny+rad); @@ -288,7 +280,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float glBegin(mode); /* start with corner right-bottom */ - if(roundboxtype & 4) { + if(roundboxtype & UI_CNR_BOTTOM_RIGHT) { round_box_shade_col(colLeft, colRight, 0.0); glVertex2f(maxx-rad, miny); @@ -306,7 +298,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float } /* corner right-top */ - if(roundboxtype & 2) { + if(roundboxtype & UI_CNR_TOP_RIGHT) { round_box_shade_col(colLeft, colRight, 0.0); glVertex2f(maxx, maxy-rad); @@ -324,7 +316,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float } /* corner left-top */ - if(roundboxtype & 1) { + if(roundboxtype & UI_CNR_TOP_LEFT) { round_box_shade_col(colLeft, colRight, (div-rad)*idiv); glVertex2f(minx+rad, maxy); @@ -342,7 +334,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float } /* corner left-bottom */ - if(roundboxtype & 8) { + if(roundboxtype & UI_CNR_BOTTOM_LEFT) { round_box_shade_col(colLeft, colRight, 1.0); glVertex2f(minx, miny+rad); @@ -709,7 +701,7 @@ static void draw_scope_end(rctf *rect, GLint *scissor) /* outline */ glColor4f(0.f, 0.f, 0.f, 0.5f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_LINE_LOOP, rect->xmin-1, rect->ymin, rect->xmax+1, rect->ymax+1, 3.0f); } @@ -768,7 +760,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); /* need scissor test, histogram can draw outside of boundary */ @@ -837,7 +829,7 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); @@ -1048,7 +1040,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.3f); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); /* need scissor test, hvectorscope can draw outside of boundary */ @@ -1233,7 +1225,7 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect) /* backdrop */ glColor3ubv((unsigned char*)wcol->inner); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f); /* sphere color */ diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 803da55cea6..59bbe67a8e2 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -334,7 +334,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) } /* create buttons for an item with an RNA array */ -static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int h, int expand, int slider, int toggle, int icon_only) +static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h), int expand, int slider, int toggle, int icon_only) { uiStyle *style= layout->root->style; uiBut *but; @@ -407,7 +407,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in if (totdim != 2) return; /* only 2D matrices supported in UI so far */ w /= dim_size[0]; - h /= dim_size[1]; + /* h /= dim_size[1]; */ /* UNUSED */ for(a=0; a<len; a++) { col= a % dim_size[0]; @@ -630,7 +630,7 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i if(!ot) { ui_item_disabled(layout, opname); - RNA_warning("uiItemFullO: unknown operator '%s'\n", opname); + RNA_warning("unknown operator '%s'", opname); return PointerRNA_NULL; } @@ -737,7 +737,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname if(!ot || !ot->srna) { ui_item_disabled(layout, opname); - RNA_warning("uiItemsFullEnumO: %s '%s'\n", ot ? "unknown operator" : "operator missing srna", opname); + RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); return; } @@ -815,7 +815,7 @@ void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char /* pass */ } else { - RNA_warning("uiItemEnumO_value: %s.%s not found.\n", RNA_struct_identifier(ptr.type), propname); + RNA_warning("%s.%s not found.", RNA_struct_identifier(ptr.type), propname); return; } @@ -844,7 +844,7 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); if(item==NULL || RNA_enum_value_from_id(item, value_str, &value)==0) { if(free) MEM_freeN(item); - RNA_warning("uiItemEnumO_string: %s.%s, enum %s not found.\n", RNA_struct_identifier(ptr.type), propname, value_str); + RNA_warning("%s.%s, enum %s not found.", RNA_struct_identifier(ptr.type), propname, value_str); return; } @@ -852,7 +852,7 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char MEM_freeN(item); } else { - RNA_warning("uiItemEnumO_string: %s.%s not found.\n", RNA_struct_identifier(ptr.type), propname); + RNA_warning("%s.%s not found.", RNA_struct_identifier(ptr.type), propname); return; } @@ -1059,7 +1059,7 @@ void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, int flag, if(!prop) { ui_item_disabled(layout, propname); - RNA_warning("uiItemR: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -1072,7 +1072,7 @@ void uiItemEnumR(uiLayout *layout, const char *name, int icon, struct PointerRNA if(!prop || RNA_property_type(prop) != PROP_ENUM) { ui_item_disabled(layout, propname); - RNA_warning("uiItemEnumR: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -1087,7 +1087,7 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr if(!prop || RNA_property_type(prop) != PROP_ENUM) { ui_item_disabled(layout, propname); - RNA_warning("uiItemEnumR_string: enum property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("enum property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -1096,7 +1096,7 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr if(!RNA_enum_value_from_id(item, value, &ivalue)) { if(free) MEM_freeN(item); ui_item_disabled(layout, propname); - RNA_warning("uiItemEnumR: enum property value not found: %s\n", value); + RNA_warning("enum property value not found: %s", value); return; } @@ -1121,12 +1121,12 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname if(!prop) { ui_item_disabled(layout, propname); - RNA_warning("uiItemsEnumR: enum property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("enum property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } if(RNA_property_type(prop) != PROP_ENUM) { - RNA_warning("uiItemsEnumR: not an enum property: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("not an enum property: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } else { @@ -1314,13 +1314,13 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna prop= RNA_struct_find_property(ptr, propname); if(!prop) { - RNA_warning("uiItemPointerR: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } type= RNA_property_type(prop); if(!ELEM(type, PROP_POINTER, PROP_STRING)) { - RNA_warning("uiItemPointerR: property %s must be a pointer or string.\n", propname); + RNA_warning("property %s must be a pointer or string.", propname); return; } @@ -1328,11 +1328,11 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna if(!searchprop) { - RNA_warning("uiItemPointerR: search collection property not found: %s.%s\n", RNA_struct_identifier(ptr->type), searchpropname); + RNA_warning("search collection property not found: %s.%s", RNA_struct_identifier(ptr->type), searchpropname); return; } else if (RNA_property_type(searchprop) != PROP_COLLECTION) { - RNA_warning("uiItemPointerR: search collection property is not a collection type: %s.%s\n", RNA_struct_identifier(ptr->type), searchpropname); + RNA_warning("search collection property is not a collection type: %s.%s", RNA_struct_identifier(ptr->type), searchpropname); return; } @@ -1417,7 +1417,7 @@ void uiItemM(uiLayout *layout, bContext *UNUSED(C), const char *menuname, const mt= WM_menutype_find(menuname, FALSE); if(mt==NULL) { - RNA_warning("uiItemM: not found %s\n", menuname); + RNA_warning("not found %s", menuname); return; } @@ -1537,12 +1537,12 @@ void uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, if(!ot) { ui_item_disabled(layout, opname); - RNA_warning("uiItemMenuEnumO: unknown operator '%s'\n", opname); + RNA_warning("unknown operator '%s'", opname); return; } if(!ot->srna) { ui_item_disabled(layout, opname); - RNA_warning("uiItemMenuEnumO: operator missing srna '%s'\n", opname); + RNA_warning("operator missing srna '%s'", opname); return; } @@ -1575,7 +1575,7 @@ void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propn prop= RNA_struct_find_property(ptr, propname); if(!prop) { ui_item_disabled(layout, propname); - RNA_warning("uiItemMenuEnumR: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 3b20533dcd4..cd1d250d6a4 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -537,8 +537,8 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) /* in some occasions, draw a border */ if(panel->flag & PNL_SELECT) { - if(panel->control & UI_PNL_SOLID) uiSetRoundBox(15); - else uiSetRoundBox(3); + if(panel->control & UI_PNL_SOLID) uiSetRoundBox(UI_CNR_ALL); + else uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); UI_ThemeColorShade(TH_BACK, -120); uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax+1, 8); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d2cee11c755..8c151712f95 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -245,7 +245,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) switch(event) { case UI_ID_BROWSE: case UI_ID_PIN: - RNA_warning("warning, id event %d shouldnt come here\n", event); + RNA_warning("warning, id event %d shouldnt come here", event); break; case UI_ID_OPEN: case UI_ID_ADD_NEW: @@ -488,7 +488,7 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const prop= RNA_struct_find_property(ptr, propname); if(!prop || RNA_property_type(prop) != PROP_POINTER) { - RNA_warning("uiTemplateID: pointer property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -549,11 +549,11 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co propType= RNA_struct_find_property(ptr, proptypename); if (!propID || RNA_property_type(propID) != PROP_POINTER) { - RNA_warning("uiTemplateAnyID: pointer property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } if (!propType || RNA_property_type(propType) != PROP_ENUM) { - RNA_warning("uiTemplateAnyID: pointer-type property not found: %s.%s\n", RNA_struct_identifier(ptr->type), proptypename); + RNA_warning("pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename); return; } @@ -592,7 +592,7 @@ void uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propna /* check that properties are valid */ propPath= RNA_struct_find_property(ptr, propname); if (!propPath || RNA_property_type(propPath) != PROP_STRING) { - RNA_warning("uiTemplatePathBuilder: path property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -855,7 +855,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) /* verify we have valid data */ if(!RNA_struct_is_a(ptr->type, &RNA_Modifier)) { - RNA_warning("uiTemplateModifier: Expected modifier on object.\n"); + RNA_warning("Expected modifier on object."); return NULL; } @@ -863,7 +863,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) md= ptr->data; if(!ob || !(GS(ob->id.name) == ID_OB)) { - RNA_warning("uiTemplateModifier: Expected modifier on object.\n"); + RNA_warning("expected modifier on object."); return NULL; } @@ -1084,7 +1084,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr) /* verify we have valid data */ if(!RNA_struct_is_a(ptr->type, &RNA_Constraint)) { - RNA_warning("uiTemplateConstraint: Expected constraint on object.\n"); + RNA_warning("Expected constraint on object."); return NULL; } @@ -1092,7 +1092,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr) con= ptr->data; if(!ob || !(GS(ob->id.name) == ID_OB)) { - RNA_warning("uiTemplateConstraint: Expected constraint on object.\n"); + RNA_warning("Expected constraint on object."); return NULL; } @@ -1138,7 +1138,7 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M PointerRNA texture_ptr; if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) { - RNA_warning("uiTemplatePreview: Expected ID of type material, texture, lamp or world.\n"); + RNA_warning("expected ID of type material, texture, lamp or world."); return; } @@ -1844,12 +1844,14 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn PointerRNA cptr; if(!prop) { - RNA_warning("uiTemplateCurveMapping: curve property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("curve property not found: %s.%s", + RNA_struct_identifier(ptr->type), propname); return; } if(RNA_property_type(prop) != PROP_POINTER) { - RNA_warning("uiTemplateCurveMapping: curve is not a pointer: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("curve is not a pointer: %s.%s", + RNA_struct_identifier(ptr->type), propname); return; } @@ -1879,7 +1881,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam float softmin, softmax, step, precision; if (!prop) { - RNA_warning("uiTemplateColorWheel: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -1949,7 +1951,7 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname, prop= RNA_struct_find_property(ptr, propname); if (!prop) { - RNA_warning("uiTemplateLayer: layers property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } @@ -1966,7 +1968,7 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname, if(used_ptr && used_propname) { used_prop= RNA_struct_find_property(used_ptr, used_propname); if (!used_prop) { - RNA_warning("uiTemplateLayer: used layers property not found: %s.%s\n", RNA_struct_identifier(ptr->type), used_propname); + RNA_warning("used layers property not found: %s.%s", RNA_struct_identifier(ptr->type), used_propname); return; } @@ -2157,7 +2159,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * pa= block->panel; if(!pa) { - RNA_warning("uiTemplateList: only works inside a panel.\n"); + RNA_warning("only works inside a panel."); return; } @@ -2167,28 +2169,28 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * if(ptr->data) { prop= RNA_struct_find_property(ptr, propname); if(!prop) { - RNA_warning("uiTemplateList: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } } activeprop= RNA_struct_find_property(activeptr, activepropname); if(!activeprop) { - RNA_warning("uiTemplateList: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), activepropname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), activepropname); return; } if(prop) { type= RNA_property_type(prop); if(type != PROP_COLLECTION) { - RNA_warning("uiTemplateList: Expected collection property.\n"); + RNA_warning("uiExpected collection property."); return; } } activetype= RNA_property_type(activeprop); if(activetype != PROP_INT) { - RNA_warning("uiTemplateList: Expected integer property.\n"); + RNA_warning("expected integer property."); return; } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 5da875356ea..c36742f7c4d 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -79,19 +79,23 @@ /* it has outline, back, and two optional tria meshes */ typedef struct uiWidgetTrias { - int tot; + unsigned int tot; float vec[32][2]; - int (*index)[3]; + unsigned int (*index)[3]; } uiWidgetTrias; +/* max as used by round_box__edges */ +#define WIDGET_CURVE_RESOLU 9 +#define WIDGET_SIZE_MAX (WIDGET_CURVE_RESOLU*4) + typedef struct uiWidgetBase { int totvert, halfwayvert; - float outer_v[64][2]; - float inner_v[64][2]; - float inner_uv[64][2]; + float outer_v[WIDGET_SIZE_MAX][2]; + float inner_v[WIDGET_SIZE_MAX][2]; + float inner_uv[WIDGET_SIZE_MAX][2]; short inner, outline, emboss; /* set on/off */ short shadedir; @@ -123,7 +127,7 @@ typedef struct uiWidgetType { /* *********************** draw data ************************** */ -static float cornervec[9][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, +static float cornervec[WIDGET_CURVE_RESOLU][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}}; static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820}, @@ -133,7 +137,7 @@ static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820}, static float num_tria_vert[3][2]= { {-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353}}; -static int num_tria_face[1][3]= { +static unsigned int num_tria_face[1][3]= { {0, 1, 2}}; static float scroll_circle_vert[16][2]= { @@ -142,7 +146,7 @@ static float scroll_circle_vert[16][2]= { {-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107}, {0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}}; -static int scroll_circle_face[14][3]= { +static unsigned int scroll_circle_face[14][3]= { {0, 1, 2}, {2, 0, 3}, {3, 0, 15}, {3, 15, 4}, {4, 15, 14}, {4, 14, 5}, {5, 14, 13}, {5, 13, 6}, {6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9}}; @@ -150,13 +154,13 @@ static float menu_tria_vert[6][2]= { {-0.41, 0.16}, {0.41, 0.16}, {0, 0.82}, {0, -0.82}, {-0.41, -0.16}, {0.41, -0.16}}; -static int menu_tria_face[2][3]= {{2, 0, 1}, {3, 5, 4}}; +static unsigned int menu_tria_face[2][3]= {{2, 0, 1}, {3, 5, 4}}; static float check_tria_vert[6][2]= { {-0.578579, 0.253369}, {-0.392773, 0.412794}, {-0.004241, -0.328551}, {-0.003001, 0.034320}, {1.055313, 0.864744}, {0.866408, 1.026895}}; -static int check_tria_face[4][3]= { +static unsigned int check_tria_face[4][3]= { {3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}}; GLubyte checker_stipple_sml[32*32/8] = @@ -175,6 +179,7 @@ GLubyte checker_stipple_sml[32*32/8] = void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3) { + float tri_arr[3][2]= {{x1, y1}, {x2, y2}, {x3, y3}}; float color[4]; int j; @@ -182,20 +187,18 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y glGetFloatv(GL_CURRENT_COLOR, color); color[3] *= 0.125f; glColor4fv(color); - + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, tri_arr); + /* for each AA step */ for(j=0; j<8; j++) { glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); - - glBegin(GL_POLYGON); - glVertex2f(x1, y1); - glVertex2f(x2, y2); - glVertex2f(x3, y3); - glEnd(); - + glDrawArrays(GL_TRIANGLES, 0, 3); glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); } + glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); } @@ -216,7 +219,7 @@ static void widget_init(uiWidgetBase *wtb) /* return tot */ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step) { - float vec[9][2]; + float vec[WIDGET_CURVE_RESOLU][2]; float minx, miny, maxx, maxy; int a, tot= 0; @@ -231,59 +234,59 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r maxy= rect->ymax+step; /* mult */ - for(a=0; a<9; a++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++) { vec[a][0]= rad*cornervec[a][0]; vec[a][1]= rad*cornervec[a][1]; } /* start with left-top, anti clockwise */ - if(roundboxalign & 1) { - for(a=0; a<9; a++, tot++) { + if(roundboxalign & UI_CNR_TOP_LEFT) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= minx+rad-vec[a][0]; vert[tot][1]= maxy-vec[a][1]; } } else { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= minx; vert[tot][1]= maxy; } } - if(roundboxalign & 8) { - for(a=0; a<9; a++, tot++) { + if(roundboxalign & UI_CNR_BOTTOM_LEFT) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= minx+vec[a][1]; vert[tot][1]= miny+rad-vec[a][0]; } } else { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= minx; vert[tot][1]= miny; } } - if(roundboxalign & 4) { - for(a=0; a<9; a++, tot++) { + if(roundboxalign & UI_CNR_BOTTOM_RIGHT) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= maxx-rad+vec[a][0]; vert[tot][1]= miny+vec[a][1]; } } else { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= maxx; vert[tot][1]= miny; } } - if(roundboxalign & 2) { - for(a=0; a<9; a++, tot++) { + if(roundboxalign & UI_CNR_TOP_RIGHT) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= maxx-vec[a][1]; vert[tot][1]= maxy-rad+vec[a][0]; } } else { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { vert[tot][0]= maxx; vert[tot][1]= maxy; } @@ -294,7 +297,7 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r /* this call has 1 extra arg to allow mask outline */ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi) { - float vec[9][2], veci[9][2]; + float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2]; float minx= rect->xmin, miny= rect->ymin, maxx= rect->xmax, maxy= rect->ymax; float minxi= minx + 1.0f; /* boundbox inner */ float maxxi= maxx - 1.0f; @@ -303,8 +306,10 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl float facxi= (maxxi!=minxi) ? 1.0f/(maxxi-minxi) : 0.0f; /* for uv, can divide by zero */ float facyi= (maxyi!=minyi) ? 1.0f/(maxyi-minyi) : 0.0f; int a, tot= 0, minsize; - const int hnum= ((roundboxalign & (1|2))==(1|2) || (roundboxalign & (4|8))==(4|8)) ? 1 : 2; - const int vnum= ((roundboxalign & (1|8))==(1|8) || (roundboxalign & (2|4))==(2|4)) ? 1 : 2; + const int hnum= ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT))==(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT) || + (roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT))==(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)) ? 1 : 2; + const int vnum= ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT))==(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT) || + (roundboxalign & (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT))==(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ? 1 : 2; minsize= MIN2((rect->xmax-rect->xmin)*hnum, (rect->ymax-rect->ymin)*vnum); @@ -315,7 +320,7 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl radi= 0.5f*minsize - 1.0f; /* mult */ - for(a=0; a<9; a++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++) { veci[a][0]= radi*cornervec[a][0]; veci[a][1]= radi*cornervec[a][1]; vec[a][0]= rad*cornervec[a][0]; @@ -323,9 +328,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl } /* corner left-bottom */ - if(roundboxalign & 8) { + if(roundboxalign & UI_CNR_BOTTOM_LEFT) { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { wt->inner_v[tot][0]= minxi+veci[a][1]; wt->inner_v[tot][1]= minyi+radi-veci[a][0]; @@ -350,9 +355,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl } /* corner right-bottom */ - if(roundboxalign & 4) { + if(roundboxalign & UI_CNR_BOTTOM_RIGHT) { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { wt->inner_v[tot][0]= maxxi-radi+veci[a][0]; wt->inner_v[tot][1]= minyi+veci[a][1]; @@ -379,9 +384,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl wt->halfwayvert= tot; /* corner right-top */ - if(roundboxalign & 2) { + if(roundboxalign & UI_CNR_TOP_RIGHT) { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { wt->inner_v[tot][0]= maxxi-veci[a][1]; wt->inner_v[tot][1]= maxyi-radi+veci[a][0]; @@ -406,9 +411,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl } /* corner left-top */ - if(roundboxalign & 1) { + if(roundboxalign & UI_CNR_TOP_LEFT) { - for(a=0; a<9; a++, tot++) { + for(a=0; a < WIDGET_CURVE_RESOLU; a++, tot++) { wt->inner_v[tot][0]= minxi+radi-veci[a][0]; wt->inner_v[tot][1]= maxyi-veci[a][1]; @@ -433,7 +438,9 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl tot++; } - + + BLI_assert(tot <= WIDGET_SIZE_MAX); + wt->totvert= tot; } @@ -516,16 +523,10 @@ static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize static void widget_trias_draw(uiWidgetTrias *tria) { - int a; - - glBegin(GL_TRIANGLES); - for(a=0; a<tria->tot; a++) { - glVertex2fv(tria->vec[ tria->index[a][0] ]); - glVertex2fv(tria->vec[ tria->index[a][1] ]); - glVertex2fv(tria->vec[ tria->index[a][2] ]); - } - glEnd(); - + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, tria->vec); + glDrawElements(GL_TRIANGLES, tria->tot*3, GL_UNSIGNED_INT, tria->index); + glDisableClientState(GL_VERTEX_ARRAY); } static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) @@ -601,19 +602,48 @@ static void round_box_shade_col4(const char col1[4], const char col2[4], const f glColor4ubv(col); } -static void widgetbase_outline(uiWidgetBase *wtb) +static void round_box_shade_col4_r(unsigned char col_r[4], const char col1[4], const char col2[4], const float fac) +{ + const int faci= FTOCHAR(fac); + const int facm= 255-faci; + + col_r[0]= (faci*col1[0] + facm*col2[0])>>8; + col_r[1]= (faci*col1[1] + facm*col2[1])>>8; + col_r[2]= (faci*col1[2] + facm*col2[2])>>8; + col_r[3]= (faci*col1[3] + facm*col2[3])>>8; +} + +static void widget_verts_to_quad_strip(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX*2+2][2]) { int a; - - /* outline */ - glBegin(GL_QUAD_STRIP); - for(a=0; a<wtb->totvert; a++) { - glVertex2fv(wtb->outer_v[a]); - glVertex2fv(wtb->inner_v[a]); + for(a=0; a<totvert; a++) { + copy_v2_v2(quad_strip[a*2], wtb->outer_v[a]); + copy_v2_v2(quad_strip[a*2+1], wtb->inner_v[a]); } - glVertex2fv(wtb->outer_v[0]); - glVertex2fv(wtb->inner_v[0]); - glEnd(); + copy_v2_v2(quad_strip[a*2], wtb->outer_v[0]); + copy_v2_v2(quad_strip[a*2+1], wtb->inner_v[0]); +} + +static void widget_verts_to_quad_strip_open(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX*2][2]) +{ + int a; + for(a=0; a<totvert; a++) { + quad_strip[a*2][0]= wtb->outer_v[a][0]; + quad_strip[a*2][1]= wtb->outer_v[a][1]; + quad_strip[a*2+1][0]= wtb->outer_v[a][0]; + quad_strip[a*2+1][1]= wtb->outer_v[a][1] - 1.0f; + } +} + +static void widgetbase_outline(uiWidgetBase *wtb) +{ + float quad_strip[WIDGET_SIZE_MAX*2+2][2]; /* + 2 because the last pair is wrapped */ + widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, quad_strip); + glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert*2 + 2); + glDisableClientState(GL_VERTEX_ARRAY); } static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) @@ -626,100 +656,124 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) if(wtb->inner) { if(wcol->shaded==0) { if (wcol->alpha_check) { + float inner_v_half[WIDGET_SIZE_MAX][2]; float x_mid= 0.0f; /* used for dumb clamping of values */ /* dark checkers */ glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); - glBegin(GL_POLYGON); - for(a=0; a<wtb->totvert; a++) { - glVertex2fv(wtb->inner_v[a]); - } - glEnd(); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); + glDrawArrays(GL_POLYGON, 0, wtb->totvert); + glDisableClientState(GL_VERTEX_ARRAY); /* light checkers */ glEnable(GL_POLYGON_STIPPLE); glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); glPolygonStipple(checker_stipple_sml); - glBegin(GL_POLYGON); - for(a=0; a<wtb->totvert; a++) { - glVertex2fv(wtb->inner_v[a]); - } - glEnd(); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); + glDrawArrays(GL_POLYGON, 0, wtb->totvert); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_POLYGON_STIPPLE); /* alpha fill */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4ubv((unsigned char*)wcol->inner); - glBegin(GL_POLYGON); + glEnableClientState(GL_VERTEX_ARRAY); + for(a=0; a<wtb->totvert; a++) { - glVertex2fv(wtb->inner_v[a]); x_mid += wtb->inner_v[a][0]; } x_mid /= wtb->totvert; - glEnd(); + + glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); + glDrawArrays(GL_POLYGON, 0, wtb->totvert); + glDisableClientState(GL_VERTEX_ARRAY); /* 1/2 solid color */ glColor4ub(wcol->inner[0], wcol->inner[1], wcol->inner[2], 255); - glBegin(GL_POLYGON); - for(a=0; a<wtb->totvert; a++) - glVertex2f(MIN2(wtb->inner_v[a][0], x_mid), wtb->inner_v[a][1]); - glEnd(); + + for(a=0; a<wtb->totvert; a++) { + inner_v_half[a][0]= MIN2(wtb->inner_v[a][0], x_mid); + inner_v_half[a][1]= wtb->inner_v[a][1]; + } + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, inner_v_half); + glDrawArrays(GL_POLYGON, 0, wtb->totvert); + glDisableClientState(GL_VERTEX_ARRAY); } else { /* simple fill */ glColor4ubv((unsigned char*)wcol->inner); - glBegin(GL_POLYGON); - for(a=0; a<wtb->totvert; a++) - glVertex2fv(wtb->inner_v[a]); - glEnd(); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); + glDrawArrays(GL_POLYGON, 0, wtb->totvert); + glDisableClientState(GL_VERTEX_ARRAY); } } else { char col1[4], col2[4]; + unsigned char col_array[WIDGET_SIZE_MAX * 4]; + unsigned char *col_pt= col_array; shadecolors4(col1, col2, wcol->inner, wcol->shadetop, wcol->shadedown); glShadeModel(GL_SMOOTH); - glBegin(GL_POLYGON); - for(a=0; a<wtb->totvert; a++) { - round_box_shade_col4(col1, col2, wtb->inner_uv[a][wtb->shadedir]); - glVertex2fv(wtb->inner_v[a]); + for(a=0; a<wtb->totvert; a++, col_pt += 4) { + round_box_shade_col4_r(col_pt, col1, col2, wtb->inner_uv[a][wtb->shadedir]); } - glEnd(); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, col_array); + glDrawArrays(GL_POLYGON, 0, wtb->totvert); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glShadeModel(GL_FLAT); } } /* for each AA step */ if(wtb->outline) { + float quad_strip[WIDGET_SIZE_MAX*2+2][2]; /* + 2 because the last pair is wrapped */ + float quad_strip_emboss[WIDGET_SIZE_MAX*2][2]; /* only for emboss */ + + widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip); + + if(wtb->emboss) { + widget_verts_to_quad_strip_open(wtb, wtb->halfwayvert, quad_strip_emboss); + } + + glEnableClientState(GL_VERTEX_ARRAY); + for(j=0; j<8; j++) { glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); /* outline */ glColor4ub(wcol->outline[0], wcol->outline[1], wcol->outline[2], 32); - glBegin(GL_QUAD_STRIP); - for(a=0; a<wtb->totvert; a++) { - glVertex2fv(wtb->outer_v[a]); - glVertex2fv(wtb->inner_v[a]); - } - glVertex2fv(wtb->outer_v[0]); - glVertex2fv(wtb->inner_v[0]); - glEnd(); + + glVertexPointer(2, GL_FLOAT, 0, quad_strip); + glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert*2 + 2); /* emboss bottom shadow */ if(wtb->emboss) { glColor4f(1.0f, 1.0f, 1.0f, 0.02f); - glBegin(GL_QUAD_STRIP); - for(a=0; a<wtb->halfwayvert; a++) { - glVertex2fv(wtb->outer_v[a]); - glVertex2f(wtb->outer_v[a][0], wtb->outer_v[a][1]-1.0f); - } - glEnd(); + + glVertexPointer(2, GL_FLOAT, 0, quad_strip_emboss); + glDrawArrays(GL_QUAD_STRIP, 0, wtb->halfwayvert*2); } glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); } + + glDisableClientState(GL_VERTEX_ARRAY); } /* decoration */ @@ -1611,7 +1665,8 @@ static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float uiWidgetBase wtb; rcti rect1= *rect; float alpha, alphastep; - int step, tot, a; + int step, totvert; + float quad_strip[WIDGET_SIZE_MAX*2][2]; /* prevent tooltips to not show round shadow */ if( 2.0f*radout > 0.2f*(rect1.ymax-rect1.ymin) ) @@ -1620,31 +1675,32 @@ static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float rect1.ymax -= 2.0f*radout; /* inner part */ - tot= round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & 12, 0.0f); - + totvert= round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f); + /* inverse linear shadow alpha */ alpha= 0.15; alphastep= 0.67; + glEnableClientState(GL_VERTEX_ARRAY); + for(step= 1; step<=radout; step++, alpha*=alphastep) { - round_box_shadow_edges(wtb.outer_v, &rect1, radin, 15, (float)step); + round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step); glColor4f(0.0f, 0.0f, 0.0f, alpha); - - glBegin(GL_QUAD_STRIP); - for(a=0; a<tot; a++) { - glVertex2fv(wtb.outer_v[a]); - glVertex2fv(wtb.inner_v[a]); - } - glEnd(); + + widget_verts_to_quad_strip_open(&wtb, totvert, quad_strip); + + glVertexPointer(2, GL_FLOAT, 0, quad_strip); + glDrawArrays(GL_QUAD_STRIP, 0, totvert*2); } - + + glDisableClientState(GL_VERTEX_ARRAY); } static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction) { uiWidgetBase wtb; - int roundboxalign= 15; + int roundboxalign= UI_CNR_ALL; widget_init(&wtb); @@ -1654,11 +1710,11 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir //rect->ymax += 4.0; } else if (direction == UI_DOWN) { - roundboxalign= 12; + roundboxalign= (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); rect->ymin -= 4.0; } else if (direction == UI_TOP) { - roundboxalign= 3; + roundboxalign= UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; rect->ymax += 4.0; } @@ -2008,7 +2064,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) widget_init(&wtb); /* fully rounded */ - round_box_edges(&wtb, 15, rect, rad); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); /* setup temp colors */ wcol_tmp.outline[0]= wcol_tmp.outline[1]= wcol_tmp.outline[2]= 0; @@ -2107,17 +2163,15 @@ void ui_draw_link_bezier(rcti *rect) if(ui_link_bezier_points(rect, coord_array, LINK_RESOL)) { /* we can reuse the dist variable here to increment the GL curve eval amount*/ // const float dist= 1.0f/(float)LINK_RESOL; // UNUSED - int i; glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); - - glBegin(GL_LINE_STRIP); - for(i=0; i<=LINK_RESOL; i++) { - glVertex2fv(coord_array[i]); - } - glEnd(); - + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, coord_array); + glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); @@ -2148,7 +2202,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat if(horizontal) SWAP(short, wcol->shadetop, wcol->shadedown); - round_box_edges(&wtb, 15, rect, rad); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); /* slider */ @@ -2176,7 +2230,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat if (state & UI_SCROLL_NO_OUTLINE) SWAP(short, outline, wtb.outline); - round_box_edges(&wtb, 15, slider, rad); + round_box_edges(&wtb, UI_CNR_ALL, slider, rad); if(state & UI_SCROLL_ARROWS) { if(wcol->item[0] > 48) wcol->item[0]-= 48; @@ -2343,7 +2397,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s /* left part of slider, always rounded */ rect1.xmax= rect1.xmin + ceil(offs+1.0f); - round_box_edges(&wtb1, roundboxalign & ~6, &rect1, offs); + round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs); wtb1.outline= 0; widgetbase_draw(&wtb1, wcol); @@ -2354,7 +2408,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s offs*= (rect1.xmax + offs - rect->xmax)/offs; else offs= 0.0f; - round_box_edges(&wtb1, roundboxalign & ~9, &rect1, offs); + round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT), &rect1, offs); widgetbase_draw(&wtb1, wcol); VECCOPY(wcol->outline, outline); @@ -2436,7 +2490,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti wtb.outline= 0; /* rounded */ - round_box_edges(&wtb, 15, rect, 10.0f); + round_box_edges(&wtb, UI_CNR_ALL, rect, 10.0f); widgetbase_draw(&wtb, wcol); } } @@ -2499,7 +2553,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, 15, rect, rad); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); } @@ -2526,7 +2580,7 @@ static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta /* rounded, but no outline */ wtb.outline= 0; - round_box_edges(&wtb, 15, rect, 4.0f); + round_box_edges(&wtb, UI_CNR_ALL, rect, 4.0f); widgetbase_draw(&wtb, wcol); } @@ -2550,7 +2604,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN recttemp.ymax-= delta; /* half rounded */ - round_box_edges(&wtb, 15, &recttemp, 4.0f); + round_box_edges(&wtb, UI_CNR_ALL, &recttemp, 4.0f); /* decoration */ if(state & UI_SELECT) { @@ -2650,12 +2704,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * UI_GetThemeColor3ubv(TH_BACK, col); glColor3ubv(col); - round_box__edges(&wtb, 15, rect, 0.0f, 4.0); + round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, 4.0); widgetbase_outline(&wtb); } /* outline */ - round_box_edges(&wtb, 15, rect, 5.0f); + round_box_edges(&wtb, UI_CNR_ALL, rect, 5.0f); wtb.outline= 1; wtb.inner= 0; widgetbase_draw(&wtb, &wt->wcol); @@ -2836,37 +2890,27 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) switch(but->flag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: - return (12); - break; + return UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; case UI_BUT_ALIGN_DOWN: - return (3); - break; + return UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; case UI_BUT_ALIGN_LEFT: - return (6); - break; + return UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT; case UI_BUT_ALIGN_RIGHT: - return (9); - break; - - case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT: - return (1); - break; - case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT: - return (2); - break; - case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT: - return (8); - break; - case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT: - return (4); - break; - + return UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; + case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT: + return UI_CNR_TOP_LEFT; + case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT: + return UI_CNR_TOP_RIGHT; + case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT: + return UI_CNR_BOTTOM_LEFT; + case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT: + return UI_CNR_BOTTOM_RIGHT; default: - return (0); - break; + return 0; } - } - return 15; + } + + return UI_CNR_ALL; } /* conversion from old to new buttons, so still messy */ @@ -3104,14 +3148,14 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) uiWidgetType *wt= widget_type(UI_WTYPE_BOX); glEnable(GL_BLEND); - widget_softshadow(rect, 15, 5.0f, 8.0f); + widget_softshadow(rect, UI_CNR_ALL, 5.0f, 8.0f); glDisable(GL_BLEND); wt->state(wt, 0); if(block) - wt->draw(&wt->wcol, rect, block->flag, 15); + wt->draw(&wt->wcol, rect, block->flag, UI_CNR_ALL); else - wt->draw(&wt->wcol, rect, 0, 15); + wt->draw(&wt->wcol, rect, 0, UI_CNR_ALL); } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 692c8940a21..9b9237f70cf 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1039,6 +1039,23 @@ void UI_ColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char c glColor3ub(r, g, b); } +void UI_GetColorPtrShade3ubv(const unsigned char cp[3], unsigned char col[3], int offset) +{ + int r, g, b; + + r= offset+(int)cp[0]; + g= offset+(int)cp[1]; + b= offset+(int)cp[2]; + + CLAMP(r, 0, 255); + CLAMP(g, 0, 255); + CLAMP(b, 0, 255); + + col[0] = r; + col[1] = g; + col[2] = b; +} + // get a 3 byte color, blended and shaded between two other char color pointers void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3], float fac, int offset) { diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 7673bd8f31c..1634b464dfd 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1659,8 +1659,8 @@ static void *editMesh_to_undoMesh(void *emv) /* now copy vertices */ a = 0; for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) { - VECCOPY(evec->co, eve->co); - VECCOPY(evec->no, eve->no); + copy_v3_v3(evec->co, eve->co); + copy_v3_v3(evec->no, eve->no); evec->f= eve->f; evec->h= eve->h; @@ -1761,7 +1761,7 @@ static void undoMesh_to_editMesh(void *umv, void *emv) eve= addvertlist(em, evec->co, NULL); evar[a]= eve; - VECCOPY(eve->no, evec->no); + copy_v3_v3(eve->no, evec->no); eve->f= evec->f; eve->h= evec->h; eve->keyindex= evec->keyindex; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index fa3619883f4..0c819cd7649 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -210,7 +210,7 @@ static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event) copy_v3_v3(vec, min); normalize_v3(vec); - dot= INPR(vec, nor); + dot= dot_v3v3(vec, nor); if( fabs(dot)<0.999) { float cross[3], si, q1[4]; @@ -1486,7 +1486,7 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 3, 500); + RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500); RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "fill", 0, "Fill", ""); @@ -1527,7 +1527,7 @@ void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); + RNA_def_int(ot->srna, "vertices", 32, 2, INT_MAX, "Vertices", "", 2, 500); RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "cap_ends", 1, "Cap Ends", ""); @@ -1568,7 +1568,7 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); + RNA_def_int(ot->srna, "vertices", 32, 2, INT_MAX, "Vertices", "", 2, 500); RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "cap_end", 1, "Cap End", ""); @@ -1609,8 +1609,8 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "x_subdivisions", 10, INT_MIN, INT_MAX, "X Subdivisions", "", 3, 1000); - RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisions", "", 3, 1000); + RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000); + RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000); RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX); ED_object_add_generic_props(ot, TRUE); @@ -1682,8 +1682,8 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "segments", 32, INT_MIN, INT_MAX, "Segments", "", 3, 500); - RNA_def_int(ot->srna, "ring_count", 16, INT_MIN, INT_MAX, "Rings", "", 3, 500); + RNA_def_int(ot->srna, "segments", 32, 3, INT_MAX, "Segments", "", 3, 500); + RNA_def_int(ot->srna, "ring_count", 16, 3, INT_MAX, "Rings", "", 3, 500); RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00); ED_object_add_generic_props(ot, TRUE); @@ -1721,7 +1721,7 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "subdivisions", 2, 0, INT_MAX, "Subdivisions", "", 0, 8); + RNA_def_int(ot->srna, "subdivisions", 2, 1, INT_MAX, "Subdivisions", "", 1, 8); RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00); ED_object_add_generic_props(ot, TRUE); diff --git a/source/blender/editors/mesh/editmesh_lib.c b/source/blender/editors/mesh/editmesh_lib.c index 0afa2d01702..02b5250f67a 100644 --- a/source/blender/editors/mesh/editmesh_lib.c +++ b/source/blender/editors/mesh/editmesh_lib.c @@ -1002,7 +1002,7 @@ void EM_free_data_layer(EditMesh *em, CustomData *data, int type) static void add_normal_aligned(float *nor, float *add) { - if( INPR(nor, add) < -0.9999f) + if(dot_v3v3(nor, add) < -0.9999f) sub_v3_v3(nor, add); else add_v3_v3(nor, add); @@ -1096,13 +1096,13 @@ short extrudeflag_face_indiv(EditMesh *em, short UNUSED(flag), float *UNUSED(nor v3= addvertlist(em, efa->v3->co, efa->v3); v1->f1= v2->f1= v3->f1= 1; - VECCOPY(v1->no, efa->n); - VECCOPY(v2->no, efa->n); - VECCOPY(v3->no, efa->n); + copy_v3_v3(v1->no, efa->n); + copy_v3_v3(v2->no, efa->n); + copy_v3_v3(v3->no, efa->n); if(efa->v4) { v4= addvertlist(em, efa->v4->co, efa->v4); v4->f1= 1; - VECCOPY(v4->no, efa->n); + copy_v3_v3(v4->no, efa->n); } else v4= NULL; @@ -1310,7 +1310,7 @@ static short extrudeflag_edge(Object *obedit, EditMesh *em, short UNUSED(flag), * of the cases above to handle edges on the line of symmetry. */ for (; md; md=md->next) { - if (md->type==eModifierType_Mirror) { + if ((md->type==eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { MirrorModifierData *mmd = (MirrorModifierData*) md; if(mmd->flag & MOD_MIR_CLIPPING) { @@ -1597,7 +1597,7 @@ short extrudeflag_vert(Object *obedit, EditMesh *em, short flag, float *nor, int * of the cases above to handle edges on the line of symmetry. */ for (; md; md=md->next) { - if (md->type==eModifierType_Mirror) { + if ((md->type==eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { MirrorModifierData *mmd = (MirrorModifierData*) md; if(mmd->flag & MOD_MIR_CLIPPING) { @@ -1648,8 +1648,8 @@ short extrudeflag_vert(Object *obedit, EditMesh *em, short flag, float *nor, int sel= 1; v1= addvertlist(em, 0, NULL); - VECCOPY(v1->co, eve->co); - VECCOPY(v1->no, eve->no); + copy_v3_v3(v1->co, eve->co); + copy_v3_v3(v1->no, eve->no); v1->f= eve->f; eve->f &= ~flag; eve->tmp.v = v1; @@ -2482,7 +2482,7 @@ void EM_make_hq_normals(EditMesh *em) /* only one face attached to that edge */ /* an edge without another attached- the weight on this is * undefined, M_PI/2 is 90d in radians and that seems good enough */ - VECCOPY(edge_normal, EM_get_face_for_index(edge_ref->f1)->n) + copy_v3_v3(edge_normal, EM_get_face_for_index(edge_ref->f1)->n); mul_v3_fl(edge_normal, M_PI/2); } add_v3_v3(EM_get_vert_for_index(ed_v1)->no, edge_normal ); @@ -2499,7 +2499,7 @@ void EM_make_hq_normals(EditMesh *em) if(normalize_v3(eve->no) == 0.0f && eve->tmp.l < 0) { /* exceptional case, totally flat */ efa= EM_get_face_for_index(-(eve->tmp.l) - 1); - VECCOPY(eve->no, efa->n); + copy_v3_v3(eve->no, efa->n); } } diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 7f82cf0ff3b..27cc2b755e6 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -829,7 +829,7 @@ static int similar_face_select__internal(EditMesh *em, int mode, float thresh) float angle; for(efa= em->faces.first; efa; efa= efa->next) { if (!(efa->f & SELECT) && !efa->h) { - angle= RAD2DEGF(angle_v2v2(base_efa->n, efa->n)); + angle= RAD2DEGF(angle_v3v3(base_efa->n, efa->n)); if (angle/180.0f<=thresh) { EM_select_face(efa, 1); selcount++; @@ -844,7 +844,7 @@ static int similar_face_select__internal(EditMesh *em, int mode, float thresh) base_dot= dot_v3v3(base_efa->cent, base_efa->n); for(efa= em->faces.first; efa; efa= efa->next) { if (!(efa->f & SELECT) && !efa->h) { - angle= RAD2DEGF(angle_v2v2(base_efa->n, efa->n)); + angle= RAD2DEGF(angle_v3v3(base_efa->n, efa->n)); if (angle/180.0f<=thresh) { dot=dot_v3v3(efa->cent, base_efa->n); if (fabsf(base_dot-dot) <= thresh) { @@ -961,7 +961,7 @@ static int similar_edge_select__internal(EditMesh *em, int mode, float thresh) else if (eed->f2==0) /* first access, assign the face */ eed->tmp.f= efa; else if (eed->f2==1) /* second, we assign the angle*/ - eed->tmp.fp= RAD2DEGF(angle_v2v2(eed->tmp.f->n, efa->n))/180; + eed->tmp.fp= RAD2DEGF(angle_v3v3(eed->tmp.f->n, efa->n))/180; eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/ } j++; @@ -991,7 +991,7 @@ static int similar_edge_select__internal(EditMesh *em, int mode, float thresh) for(eed= em->edges.first; eed; eed= eed->next) { if (!(eed->f & SELECT) && !eed->h) { sub_v3_v3v3(dir, eed->v1->co, eed->v2->co); - angle= RAD2DEGF(angle_v2v2(base_dir, dir)); + angle= RAD2DEGF(angle_v3v3(base_dir, dir)); if (angle>90.0f) /* use the smallest angle between the edges */ angle= fabsf(angle-180.0f); @@ -1088,7 +1088,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) Mesh *me= obedit->data; EditMesh *em= BKE_mesh_get_editmesh(me); - int selcount = similar_edge_select__internal(em, RNA_int_get(op->ptr, "type"), RNA_float_get(op->ptr, "threshold")); + int selcount = similar_edge_select__internal(em, RNA_enum_get(op->ptr, "type"), RNA_float_get(op->ptr, "threshold")); if (selcount) { /* here was an edge-mode only select flush case, has to be generalized */ @@ -1161,7 +1161,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) float angle; for(eve= em->verts.first; eve; eve= eve->next) { if (!(eve->f & SELECT) && !eve->h) { - angle= RAD2DEGF(angle_v2v2(base_eve->no, eve->no)); + angle= RAD2DEGF(angle_v3v3(base_eve->no, eve->no)); if (angle/180.0f<=thresh) { eve->f |= SELECT; selcount++; @@ -4150,7 +4150,7 @@ static int smooth_vertex(bContext *C, wmOperator *op) * are within tolerance of the plane(s) of reflection */ for(md=obedit->modifiers.first; md; md=md->next) { - if(md->type==eModifierType_Mirror) { + if((md->type==eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { MirrorModifierData *mmd = (MirrorModifierData*) md; if(mmd->flag & MOD_MIR_CLIPPING) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9ff2923f733..2dc82ae89fb 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1466,8 +1466,8 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int sub_v3_v3v3(nor, edge->v1->co, edge->v2->co); len= 0.5f*normalize_v3(nor); - VECCOPY(nor1, edge->v1->no); - VECCOPY(nor2, edge->v2->no); + copy_v3_v3(nor1, edge->v1->no); + copy_v3_v3(nor2, edge->v2->no); /* cosine angle */ fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ; @@ -2675,7 +2675,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float } for (; md; md=md->next) { - if (md->type==eModifierType_Mirror) { + if ((md->type==eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { MirrorModifierData *mmd = (MirrorModifierData*) md; if(mmd->flag & MOD_MIR_CLIPPING) { @@ -3234,13 +3234,13 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert normal_tri_v3( noA2,v1->co, v3->co, v4->co); if(noA1[0] == noA2[0] && noA1[1] == noA2[1] && noA1[2] == noA2[2]) normalADiff = 0.0; - else normalADiff = RAD2DEGF(angle_v2v2(noA1, noA2)); + else normalADiff = RAD2DEGF(angle_v3v3(noA1, noA2)); //if(!normalADiff) normalADiff = 179; normal_tri_v3( noB1,v2->co, v3->co, v4->co); normal_tri_v3( noB2,v4->co, v1->co, v2->co); if(noB1[0] == noB2[0] && noB1[1] == noB2[1] && noB1[2] == noB2[2]) normalBDiff = 0.0; - else normalBDiff = RAD2DEGF(angle_v2v2(noB1, noB2)); + else normalBDiff = RAD2DEGF(angle_v3v3(noB1, noB2)); //if(!normalBDiff) normalBDiff = 179; measure += (normalADiff/360) + (normalBDiff/360); @@ -3255,10 +3255,10 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert diff = 0.0; diff = ( - fabsf(RAD2DEGF(angle_v2v2(edgeVec1, edgeVec2)) - 90) + - fabsf(RAD2DEGF(angle_v2v2(edgeVec2, edgeVec3)) - 90) + - fabsf(RAD2DEGF(angle_v2v2(edgeVec3, edgeVec4)) - 90) + - fabsf(RAD2DEGF(angle_v2v2(edgeVec4, edgeVec1)) - 90)) / 360; + fabsf(RAD2DEGF(angle_v3v3(edgeVec1, edgeVec2)) - 90) + + fabsf(RAD2DEGF(angle_v3v3(edgeVec2, edgeVec3)) - 90) + + fabsf(RAD2DEGF(angle_v3v3(edgeVec3, edgeVec4)) - 90) + + fabsf(RAD2DEGF(angle_v3v3(edgeVec4, edgeVec1)) - 90)) / 360; if(!diff) return 0.0; measure += diff; @@ -4869,7 +4869,7 @@ void mesh_set_face_flags(EditMesh *em, short mode) /* helper to find edge for edge_rip */ static float mesh_rip_edgedist(ARegion *ar, float mat[][4], float *co1, float *co2, const int mval[2]) { - float vec1[3], vec2[3], mvalf[2]; + float vec1[2], vec2[2], mvalf[2]; ED_view3d_project_float(ar, co1, vec1, mat); ED_view3d_project_float(ar, co2, vec2, mat); diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 14b40d55f11..b9b8ddc6305 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -58,8 +58,22 @@ set(SRC object_intern.h ) +if(WITH_GAMEENGINE) + list(APPEND INC + ../../../../extern/recastnavigation/Recast/Include + ) + + list(APPEND SRC + object_navmesh.cpp + ) +endif() + if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() +if(WITH_GAMEENGINE) + add_definitions(-DWITH_GAMEENGINE) +endif() + blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript index ca048cb59f9..cdda16582ef 100644 --- a/source/blender/editors/object/SConscript +++ b/source/blender/editors/object/SConscript @@ -1,12 +1,13 @@ #!/usr/bin/python Import ('env') -sources = env.Glob('*.c') +sources = env.Glob('*.c') + env.Glob('*.cpp') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc ../../blenloader' incs += ' ../../makesrna ../../python ../../ikplugin' incs += ' ../../render/extern/include ../../gpu' # for object_bake.c +incs += ' #extern/recastnavigation/Recast/Include' defs = [] @@ -19,5 +20,8 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): if env['WITH_BF_PYTHON']: defs.append('WITH_PYTHON') + +if env['WITH_BF_GAMEENGINE']: + defs.append('WITH_GAMEENGINE') env.BlenderLib ( 'bf_editors_object', sources, Split(incs), defs, libtype=['core'], priority=[35] ) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 0a4c6b638a3..fb119b1d264 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -229,5 +229,10 @@ void OBJECT_OT_group_remove(struct wmOperatorType *ot); /* object_bake.c */ void OBJECT_OT_bake_image(wmOperatorType *ot); +/* object_navmesh.cpp */ +void OBJECT_OT_create_navmesh(struct wmOperatorType *ot); +void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot); +void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot); + #endif /* ED_OBJECT_INTERN_H */ diff --git a/source/blender/editors/object/object_navmesh.cpp b/source/blender/editors/object/object_navmesh.cpp new file mode 100644 index 00000000000..d0768d30236 --- /dev/null +++ b/source/blender/editors/object/object_navmesh.cpp @@ -0,0 +1,628 @@ +/** +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2004 by Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#include <math.h> +#include "Recast.h" + +extern "C" +{ +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_ID.h" + +#include "BKE_library.h" +#include "BKE_depsgraph.h" +#include "BKE_context.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_scene.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" +#include "BLI_editVert.h" +#include "BLI_listbase.h" +#include "BLI_utildefines.h" +#include "ED_object.h" +#include "BLI_math_vector.h" + +#include "RNA_access.h" + +#include "ED_mesh.h" + +/*mesh/mesh_intern.h */ +extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); +extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); +extern void free_vertlist(EditMesh *em, ListBase *edve); +extern void free_edgelist(EditMesh *em, ListBase *lb); +extern void free_facelist(EditMesh *em, ListBase *lb); + +#include "WM_api.h" +#include "WM_types.h" + +static void createVertsTrisData(bContext *C, LinkNode* obs, int& nverts, float*& verts, int &ntris, int*& tris) +{ + MVert *mvert; + int nfaces = 0, *tri, i, curnverts, basenverts, curnfaces; + MFace *mface; + float co[3], wco[3]; + Object *ob; + LinkNode *oblink, *dmlink; + DerivedMesh *dm; + Scene* scene = CTX_data_scene(C); + LinkNode* dms = NULL; + + nverts = 0; + ntris = 0; + //calculate number of verts and tris + for (oblink = obs; oblink; oblink = oblink->next) + { + ob = (Object*) oblink->link; + DerivedMesh *dm = mesh_create_derived_no_virtual(scene, ob, NULL, CD_MASK_MESH); + BLI_linklist_append(&dms, (void*)dm); + + nverts += dm->getNumVerts(dm); + nfaces = dm->getNumFaces(dm); + ntris += nfaces; + + //resolve quad faces + mface = dm->getFaceArray(dm); + for (i=0; i<nfaces; i++) + { + MFace* mf = &mface[i]; + if (mf->v4) + ntris+=1; + } + } + + //create data + verts = (float*) MEM_mallocN(sizeof(float)*3*nverts, "verts"); + tris = (int*) MEM_mallocN(sizeof(int)*3*ntris, "faces"); + + basenverts = 0; + tri = tris; + for (oblink = obs, dmlink = dms; oblink && dmlink; + oblink = oblink->next, dmlink = dmlink->next) + { + ob = (Object*) oblink->link; + dm = (DerivedMesh*) dmlink->link; + + curnverts = dm->getNumVerts(dm); + mvert = dm->getVertArray(dm); + //copy verts + for (i=0; i<curnverts; i++) + { + MVert *v = &mvert[i]; + copy_v3_v3(co, v->co); + mul_v3_m4v3(wco, ob->obmat, co); + verts[3*(basenverts+i)+0] = wco[0]; + verts[3*(basenverts+i)+1] = wco[2]; + verts[3*(basenverts+i)+2] = wco[1]; + } + + //create tris + curnfaces = dm->getNumFaces(dm); + mface = dm->getFaceArray(dm); + for (i=0; i<curnfaces; i++) + { + MFace* mf = &mface[i]; + tri[0]= basenverts + mf->v1; tri[1]= basenverts + mf->v3; tri[2]= basenverts + mf->v2; + tri += 3; + if (mf->v4) + { + tri[0]= basenverts + mf->v1; tri[1]= basenverts + mf->v4; tri[2]= basenverts + mf->v3; + tri += 3; + } + } + basenverts += curnverts; + } + + //release derived mesh + for (dmlink = dms; dmlink; dmlink = dmlink->next) + { + dm = (DerivedMesh*) dmlink->link; + dm->release(dm); + } + BLI_linklist_free(dms, NULL); +} + +static bool buildNavMesh(const RecastData& recastParams, int nverts, float* verts, int ntris, int* tris, + rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh) +{ + float bmin[3], bmax[3]; + rcHeightfield* solid; + unsigned char *triflags; + rcCompactHeightfield* chf; + rcContourSet *cset; + + rcCalcBounds(verts, nverts, bmin, bmax); + + // + // Step 1. Initialize build config. + // + rcConfig cfg; + memset(&cfg, 0, sizeof(cfg)); + { +/* + float cellsize = 0.3f; + float cellheight = 0.2f; + float agentmaxslope = M_PI/4; + float agentmaxclimb = 0.9f; + float agentheight = 2.0f; + float agentradius = 0.6f; + float edgemaxlen = 12.0f; + float edgemaxerror = 1.3f; + float regionminsize = 50.f; + float regionmergesize = 20.f; + int vertsperpoly = 6; + float detailsampledist = 6.0f; + float detailsamplemaxerror = 1.0f; + cfg.cs = cellsize; + cfg.ch = cellheight; + cfg.walkableSlopeAngle = agentmaxslope/M_PI*180.f; + cfg.walkableHeight = (int)ceilf(agentheight/ cfg.ch); + cfg.walkableClimb = (int)floorf(agentmaxclimb / cfg.ch); + cfg.walkableRadius = (int)ceilf(agentradius / cfg.cs); + cfg.maxEdgeLen = (int)(edgemaxlen/cellsize); + cfg.maxSimplificationError = edgemaxerror; + cfg.minRegionSize = (int)rcSqr(regionminsize); + cfg.mergeRegionSize = (int)rcSqr(regionmergesize); + cfg.maxVertsPerPoly = vertsperpoly; + cfg.detailSampleDist = detailsampledist< 0.9f ? 0 : cellsize * detailsampledist; + cfg.detailSampleMaxError = cellheight * detailsamplemaxerror; +*/ + cfg.cs = recastParams.cellsize; + cfg.ch = recastParams.cellheight; + cfg.walkableSlopeAngle = recastParams.agentmaxslope/((float)M_PI)*180.f; + cfg.walkableHeight = (int)ceilf(recastParams.agentheight/ cfg.ch); + cfg.walkableClimb = (int)floorf(recastParams.agentmaxclimb / cfg.ch); + cfg.walkableRadius = (int)ceilf(recastParams.agentradius / cfg.cs); + cfg.maxEdgeLen = (int)(recastParams.edgemaxlen/recastParams.cellsize); + cfg.maxSimplificationError = recastParams.edgemaxerror; + cfg.minRegionSize = (int)rcSqr(recastParams.regionminsize); + cfg.mergeRegionSize = (int)rcSqr(recastParams.regionmergesize); + cfg.maxVertsPerPoly = recastParams.vertsperpoly; + cfg.detailSampleDist = recastParams.detailsampledist< 0.9f ? 0 : + recastParams.cellsize * recastParams.detailsampledist; + cfg.detailSampleMaxError = recastParams.cellheight * recastParams.detailsamplemaxerror; + + } + + // Set the area where the navigation will be build. + vcopy(cfg.bmin, bmin); + vcopy(cfg.bmax, bmax); + rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height); + + // + // Step 2. Rasterize input polygon soup. + // + // Allocate voxel heightfield where we rasterize our input data to. + solid = new rcHeightfield; + if (!solid) + return false; + + if (!rcCreateHeightfield(*solid, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch)) + return false; + + // Allocate array that can hold triangle flags. + triflags = (unsigned char*) MEM_mallocN(sizeof(unsigned char)*ntris, "triflags"); + if (!triflags) + return false; + // Find triangles which are walkable based on their slope and rasterize them. + memset(triflags, 0, ntris*sizeof(unsigned char)); + rcMarkWalkableTriangles(cfg.walkableSlopeAngle, verts, nverts, tris, ntris, triflags); + rcRasterizeTriangles(verts, nverts, tris, triflags, ntris, *solid); + MEM_freeN(triflags); + MEM_freeN(verts); + MEM_freeN(tris); + + // + // Step 3. Filter walkables surfaces. + // + rcFilterLedgeSpans(cfg.walkableHeight, cfg.walkableClimb, *solid); + rcFilterWalkableLowHeightSpans(cfg.walkableHeight, *solid); + + // + // Step 4. Partition walkable surface to simple regions. + // + + chf = new rcCompactHeightfield; + if (!chf) + return false; + if (!rcBuildCompactHeightfield(cfg.walkableHeight, cfg.walkableClimb, RC_WALKABLE, *solid, *chf)) + return false; + + delete solid; + + // Prepare for region partitioning, by calculating distance field along the walkable surface. + if (!rcBuildDistanceField(*chf)) + return false; + + // Partition the walkable surface into simple regions without holes. + if (!rcBuildRegions(*chf, cfg.walkableRadius, cfg.borderSize, cfg.minRegionSize, cfg.mergeRegionSize)) + return false; + + // + // Step 5. Trace and simplify region contours. + // + // Create contours. + cset = new rcContourSet; + if (!cset) + return false; + + if (!rcBuildContours(*chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset)) + return false; + + // + // Step 6. Build polygons mesh from contours. + // + pmesh = new rcPolyMesh; + if (!pmesh) + return false; + if (!rcBuildPolyMesh(*cset, cfg.maxVertsPerPoly, *pmesh)) + return false; + + + // + // Step 7. Create detail mesh which allows to access approximate height on each polygon. + // + + dmesh = new rcPolyMeshDetail; + if (!dmesh) + return false; + + if (!rcBuildPolyMeshDetail(*pmesh, *chf, cfg.detailSampleDist, cfg.detailSampleMaxError, *dmesh)) + return false; + + delete chf; + delete cset; + + return true; +} + +static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh, Base* base) +{ + float co[3], rot[3]; + EditMesh *em; + int i,j, k; + unsigned short* v; + int face[3]; + Main *bmain = CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Object* obedit; + int createob = base==NULL; + zero_v3(co); + zero_v3(rot); + if (createob) + { + //create new object + obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); + } + else + { + obedit = base->object; + scene_select_base(scene, base); + copy_v3_v3(obedit->loc, co); + copy_v3_v3(obedit->rot, rot); + } + + ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); + em = BKE_mesh_get_editmesh(((Mesh *)obedit->data)); + + if (!createob) + { + //clear + if(em->verts.first) free_vertlist(em, &em->verts); + if(em->edges.first) free_edgelist(em, &em->edges); + if(em->faces.first) free_facelist(em, &em->faces); + if(em->selected.first) BLI_freelistN(&(em->selected)); + } + + //create verts for polygon mesh + for(i = 0; i < pmesh->nverts; i++) { + v = &pmesh->verts[3*i]; + co[0] = pmesh->bmin[0] + v[0]*pmesh->cs; + co[1] = pmesh->bmin[1] + v[1]*pmesh->ch; + co[2] = pmesh->bmin[2] + v[2]*pmesh->cs; + SWAP(float, co[1], co[2]); + addvertlist(em, co, NULL); + } + + //create custom data layer to save polygon idx + CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "recastData"); + + //create verts and faces for detailed mesh + for (i=0; i<dmesh->nmeshes; i++) + { + int uniquevbase = em->totvert; + unsigned short vbase = dmesh->meshes[4*i+0]; + unsigned short ndv = dmesh->meshes[4*i+1]; + unsigned short tribase = dmesh->meshes[4*i+2]; + unsigned short trinum = dmesh->meshes[4*i+3]; + const unsigned short* p = &pmesh->polys[i*pmesh->nvp*2]; + int nv = 0; + for (j = 0; j < pmesh->nvp; ++j) + { + if (p[j] == 0xffff) break; + nv++; + } + //create unique verts + for (j=nv; j<ndv; j++) + { + copy_v3_v3(co, &dmesh->verts[3*(vbase + j)]); + SWAP(float, co[1], co[2]); + addvertlist(em, co, NULL); + } + + EM_init_index_arrays(em, 1, 0, 0); + + //create faces + for (j=0; j<trinum; j++) + { + unsigned char* tri = &dmesh->tris[4*(tribase+j)]; + EditFace* newFace; + for (k=0; k<3; k++) + { + if (tri[k]<nv) + face[k] = p[tri[k]]; //shared vertex + else + face[k] = uniquevbase+tri[k]-nv; //unique vertex + } + newFace = addfacelist(em, EM_get_vert_for_index(face[0]), EM_get_vert_for_index(face[2]), + EM_get_vert_for_index(face[1]), NULL, NULL, NULL); + + //set navigation polygon idx to the custom layer + int* polygonIdx = (int*)CustomData_em_get(&em->fdata, newFace->data, CD_RECAST); + *polygonIdx = i+1; //add 1 to avoid zero idx + } + + EM_free_index_arrays(); + } + + delete pmesh; pmesh = NULL; + delete dmesh; dmesh = NULL; + + BKE_mesh_end_editmesh((Mesh*)obedit->data, em); + + DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + + ED_object_exit_editmode(C, EM_FREEDATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + if (createob) + { + obedit->gameflag &= ~OB_COLLISION; + obedit->gameflag |= OB_NAVMESH; + obedit->body_type = OB_BODY_TYPE_NAVMESH; + rename_id((ID *)obedit, "Navmesh"); + } + + ModifierData *md= modifiers_findByType(obedit, eModifierType_NavMesh); + if (!md) + { + ED_object_modifier_add(NULL, bmain, scene, obedit, NULL, eModifierType_NavMesh); + } + + return obedit; +} + +static int create_navmesh_exec(bContext *C, wmOperator *op) +{ + Scene* scene = CTX_data_scene(C); + int nverts, ntris; + float* verts; + int* tris; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; + LinkNode* obs = NULL; + Base* navmeshBase = NULL; + //CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) //expand macros to avoid error in convertion from void* + { + ListBase ctx_data_list; + CollectionPointerLink *ctx_link; + CTX_data_selected_editable_bases(C, &ctx_data_list); + for(ctx_link = (CollectionPointerLink *)ctx_data_list.first; + ctx_link; ctx_link = (CollectionPointerLink *)ctx_link->next) { + Base* base= (Base*)ctx_link->ptr.data; + { + if (base->object->body_type==OB_BODY_TYPE_NAVMESH) + { + if (!navmeshBase || base==CTX_data_active_base(C)) + navmeshBase = base; + } + else + BLI_linklist_append(&obs, (void*)base->object); + } + CTX_DATA_END; + createVertsTrisData(C, obs, nverts, verts, ntris, tris); + BLI_linklist_free(obs, NULL); + buildNavMesh(scene->gm.recastData, nverts, verts, ntris, tris, pmesh, dmesh); + createRepresentation(C, pmesh, dmesh, navmeshBase); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_create_navmesh(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Create navigation mesh"; + ot->description= "Create navigation mesh for selected objects"; + ot->idname= "OBJECT_OT_create_navmesh"; + + /* api callbacks */ + ot->exec= create_navmesh_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int assign_navpolygon_poll(bContext *C) +{ + Object *ob= (Object *)CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + if (!ob || !ob->data) + return 0; + return (((Mesh*)ob->data)->edit_mesh != NULL); +} + +static int assign_navpolygon_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + + //do work here + int targetPolyIdx = -1; + EditFace *ef, *efa; + efa = EM_get_actFace(em, 0); + if (efa) + { + if (CustomData_has_layer(&em->fdata, CD_RECAST)) + { + targetPolyIdx = *(int*)CustomData_em_get(&em->fdata, efa->data, CD_RECAST); + targetPolyIdx = targetPolyIdx>=0? targetPolyIdx : -targetPolyIdx; + if (targetPolyIdx>0) + { + //set target poly idx to other selected faces + ef = (EditFace*)em->faces.last; + while(ef) + { + if((ef->f & SELECT )&& ef!=efa) + { + int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); + *recastDataBlock = targetPolyIdx; + } + ef = ef->prev; + } + } + } + } + + DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + BKE_mesh_end_editmesh((Mesh*)obedit->data, em); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Assign polygon index"; + ot->description= "Assign polygon index to face by active face"; + ot->idname= "OBJECT_OT_assign_navpolygon"; + + /* api callbacks */ + ot->poll = assign_navpolygon_poll; + ot->exec= assign_navpolygon_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int compare(const void * a, const void * b){ + return ( *(int*)a - *(int*)b ); +} +static int findFreeNavPolyIndex(EditMesh* em) +{ + //construct vector of indices + int numfaces = em->totface; + int* indices = new int[numfaces]; + EditFace* ef = (EditFace*)em->faces.last; + int idx = 0; + while(ef) + { + int polyIdx = *(int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); + indices[idx] = polyIdx; + idx++; + ef = ef->prev; + } + qsort(indices, numfaces, sizeof(int), compare); + //search first free index + int freeIdx = 1; + for (int i=0; i<numfaces; i++) + { + if (indices[i]==freeIdx) + freeIdx++; + else if (indices[i]>freeIdx) + break; + } + delete indices; + return freeIdx; +} + +static int assign_new_navpolygon_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + + EditFace *ef; + if (CustomData_has_layer(&em->fdata, CD_RECAST)) + { + int targetPolyIdx = findFreeNavPolyIndex(em); + if (targetPolyIdx>0) + { + //set target poly idx to selected faces + ef = (EditFace*)em->faces.last; + while(ef) + { + if(ef->f & SELECT ) + { + int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); + *recastDataBlock = targetPolyIdx; + } + ef = ef->prev; + } + } + } + + DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + BKE_mesh_end_editmesh((Mesh*)obedit->data, em); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Assign new polygon index"; + ot->description= "Assign new polygon index to face"; + ot->idname= "OBJECT_OT_assign_new_navpolygon"; + + /* api callbacks */ + ot->poll = assign_navpolygon_poll; + ot->exec= assign_new_navpolygon_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} +} diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 3e8c34b7395..b36357facb1 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -218,8 +218,15 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_bake_image); WM_operatortype_append(OBJECT_OT_drop_named_material); + +#ifdef WITH_GAMEENGINE + WM_operatortype_append(OBJECT_OT_create_navmesh); + WM_operatortype_append(OBJECT_OT_assign_navpolygon); + WM_operatortype_append(OBJECT_OT_assign_new_navpolygon); +#endif } + void ED_operatormacros_object(void) { wmOperatorType *ot; diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index cb1fc7541d0..8fdd7a53e91 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -121,6 +121,20 @@ void ED_base_object_activate(bContext *C, Base *base) /********************** Selection Operators **********************/ +static int objects_selectable_poll(bContext *C) +{ + /* we don't check for linked scenes here, selection is + still allowed then for inspection of scene */ + Object *obact= CTX_data_active_object(C); + + if(CTX_data_edit_object(C)) + return 0; + if(obact && obact->mode) + return 0; + + return 1; +} + /************************ Select by Type *************************/ static int object_select_by_type_exec(bContext *C, wmOperator *op) @@ -159,7 +173,7 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot) /* api callbacks */ ot->invoke= WM_menu_invoke; ot->exec= object_select_by_type_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -341,7 +355,7 @@ void OBJECT_OT_select_linked(wmOperatorType *ot) /* api callbacks */ ot->invoke= WM_menu_invoke; ot->exec= object_select_linked_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -667,7 +681,7 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot) /* api callbacks */ ot->invoke= WM_menu_invoke; ot->exec= object_select_grouped_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -716,7 +730,7 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot) /* api callbacks */ /*ot->invoke = XXX - need a int grid popup*/ ot->exec= object_select_by_layer_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -754,7 +768,7 @@ void OBJECT_OT_select_inverse(wmOperatorType *ot) /* api callbacks */ ot->exec= object_select_inverse_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -815,7 +829,7 @@ void OBJECT_OT_select_all(wmOperatorType *ot) /* api callbacks */ ot->exec= object_select_all_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -864,7 +878,7 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot) /* api callbacks */ ot->exec= object_select_same_group_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -917,7 +931,7 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot) /* api callbacks */ ot->exec= object_select_mirror_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -974,7 +988,7 @@ void OBJECT_OT_select_name(wmOperatorType *ot) /* api callbacks */ ot->exec= object_select_name_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1022,7 +1036,7 @@ void OBJECT_OT_select_random(wmOperatorType *ot) /* api callbacks */ /*ot->invoke= object_select_random_invoke XXX - need a number popup ;*/ ot->exec = object_select_random_exec; - ot->poll= ED_operator_objectmode; + ot->poll= objects_selectable_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 1b24d660411..75c2054091c 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -529,7 +529,7 @@ void SCENE_OT_render_layer_add(wmOperatorType *ot) static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene= CTX_data_scene(C); + Scene *scene = CTX_data_scene(C), *sce; SceneRenderLayer *rl; int act= scene->r.actlay; @@ -541,15 +541,17 @@ static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op)) MEM_freeN(rl); scene->r.actlay= 0; - - if(scene->nodetree) { - bNode *node; - for(node= scene->nodetree->nodes.first; node; node= node->next) { - if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) { - if(node->custom1==act) - node->custom1= 0; - else if(node->custom1>act) - node->custom1--; + + for(sce = CTX_data_main(C)->scene.first; sce; sce = sce->id.next) { + if(sce->nodetree) { + bNode *node; + for(node = sce->nodetree->nodes.first; node; node = node->next) { + if(node->type==CMP_NODE_R_LAYERS && (Scene*)node->id==scene) { + if(node->custom1==act) + node->custom1= 0; + else if(node->custom1>act) + node->custom1--; + } } } } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index bc97cd9d3ff..d41d3245623 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -233,28 +233,28 @@ static void region_draw_azone_tab(AZone *az) /* add code to draw region hidden as 'too small' */ switch(az->edge) { case AE_TOP_TO_BOTTOMRIGHT: - uiSetRoundBox(3 + 16); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA); uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); uiRoundRect((float)az->x1, 0.3f+(float)az->y1, (float)az->x2, 0.3f+(float)az->y2, 4.0f); break; case AE_BOTTOM_TO_TOPLEFT: - uiSetRoundBox(12 + 16); + uiSetRoundBox(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA); uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); uiRoundRect((float)az->x1, 0.3f+(float)az->y1, (float)az->x2, 0.3f+(float)az->y2, 4.0f); break; case AE_LEFT_TO_TOPRIGHT: - uiSetRoundBox(9 + 16); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA); uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); uiRoundRect((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f); break; case AE_RIGHT_TO_TOPLEFT: - uiSetRoundBox(6 + 16); + uiSetRoundBox(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA); uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f); glColor4ub(0, 0, 0, 255); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b199f54cde1..62fdfc140df 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3485,8 +3485,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf) RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 1); RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 1); - RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "end", 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", 0); WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "next", 0); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 09873566d4a..9500c7f663c 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -322,8 +322,8 @@ static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); } return 1; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index ced3dd00a9c..669a9c6fdcb 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3330,7 +3330,7 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { copy_v3_v3(vd.co, unode->co[vd.i]); - if(vd.no) VECCOPY(vd.no, unode->no[vd.i]) + if(vd.no) copy_v3_v3_short(vd.no, unode->no[vd.i]); else normal_short_to_float_v3(vd.fno, unode->no[vd.i]); if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index c4ea5c9478c..a13b874e504 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -300,7 +300,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node) BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) { copy_v3_v3(unode->co[vd.i], vd.co); - if(vd.no) VECCOPY(unode->no[vd.i], vd.no) + if(vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no); else normal_float_to_short_v3(unode->no[vd.i], vd.fno); if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i]; diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 72dbbd9da9a..19cae6aa67d 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -691,7 +691,7 @@ static int bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) update_animation_flags_exec(C, NULL); - for(cfra = scene->r.sfra; cfra <= scene->r.efra; cfra++) + for(cfra = scene->r.sfra > 0 ? scene->r.sfra - 1 : 0; cfra <= scene->r.efra + 1; cfra++) { scene->r.cfra = cfra; scene_update_for_newframe(bmain, scene, scene->lay); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 9fecfda7764..0080317aece 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -239,7 +239,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar) static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade) { UI_ThemeColorShade(colorid, shade); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiRoundBox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f); } @@ -507,7 +507,7 @@ void file_draw_list(const bContext *C, ARegion *ar) draw_tile(sx, sy-1, layout->tile_w+4, sfile->layout->tile_h+layout->tile_border_y, colorid, shade); } } - uiSetRoundBox(0); + uiSetRoundBox(UI_CNR_NONE); if ( FILE_IMGDISPLAY == params->display ) { is_icon = 0; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 7382188d62a..c7ada4a5801 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1158,8 +1158,8 @@ void filelist_from_main(struct FileList *filelist) /* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */ if (!filelist->hide_parent) filelist->numfiles+= 1; - filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)); - + filelist->filelist= filelist->numfiles > 0 ? (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)) : NULL; + files = filelist->filelist; if (!filelist->hide_parent) { diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 20b001965aa..43a8747e942 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -718,6 +718,8 @@ static const char *actuator_name(int type) return "State"; case ACT_ARMATURE: return "Armature"; + case ACT_STEERING: + return "Steering"; } return "unknown"; } @@ -4345,6 +4347,48 @@ static void draw_actuator_visibility(uiLayout *layout, PointerRNA *ptr) uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE); } +static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr) +{ + uiLayout *row; + uiLayout *col; + + uiItemR(layout, ptr, "mode", 0, NULL, 0); + uiItemR(layout, ptr, "target", 0, NULL, 0); + uiItemR(layout, ptr, "navmesh", 0, NULL, 0); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "distance", 0, NULL, 0); + uiItemR(row, ptr, "velocity", 0, NULL, 0); + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "acceleration", 0, NULL, 0); + uiItemR(row, ptr, "turn_speed", 0, NULL, 0); + + row = uiLayoutRow(layout, 0); + col = uiLayoutColumn(row, 0); + uiItemR(col, ptr, "facing", 0, NULL, 0); + col = uiLayoutColumn(row, 0); + uiItemR(col, ptr, "facing_axis", 0, NULL, 0); + if (!RNA_boolean_get(ptr, "facing")) + { + uiLayoutSetActive(col, 0); + } + col = uiLayoutColumn(row, 0); + uiItemR(col, ptr, "normal_up", 0, NULL, 0); + if (!RNA_pointer_get(ptr, "navmesh").data) + { + uiLayoutSetActive(col, 0); + } + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "self_terminated", 0, NULL, 0); + if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING) + { + uiItemR(row, ptr, "update_period", 0, NULL, 0); + row = uiLayoutRow(layout, 0); + } + uiItemR(row, ptr, "show_visualization", 0, NULL, 0); +} + static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C) { uiLayout *box; @@ -4406,6 +4450,8 @@ static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C) case ACT_VISIBILITY: draw_actuator_visibility(box, ptr); break; + case ACT_STEERING: + draw_actuator_steering(box, ptr); } } diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 0c9c7877ddc..6af43e7618d 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -376,7 +376,7 @@ static void nla_draw_strip (SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStr if (nonSolo == 0) { /* strip is in normal track */ glColor3fv(color); - uiSetRoundBox(15); /* all corners rounded */ + uiSetRoundBox(UI_CNR_ALL); /* all corners rounded */ uiDrawBoxShade(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1); } @@ -811,7 +811,7 @@ static void draw_nla_channel_list_gl (bAnimContext *ac, ListBase *anim_data, Vie offset += 7 * indent; /* only on top two corners, to show that this channel sits on top of the preceding ones */ - uiSetRoundBox((1|2)); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); /* draw slightly shifted up vertically to look like it has more separtion from other channels, * but we then need to slightly shorten it so that it doesn't look like it overlaps diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c index c33316620eb..e9b45da6bce 100644 --- a/source/blender/editors/space_nla/nla_select.c +++ b/source/blender/editors/space_nla/nla_select.c @@ -226,7 +226,7 @@ static void borderselect_nla_strips (bAnimContext *ac, rcti rect, short mode, sh SpaceNla *snla = (SpaceNla *)ac->sl; View2D *v2d= &ac->ar->v2d; rctf rectf; - float ymin=(float)(-NLACHANNEL_HEIGHT(snla)), ymax=0; + float ymin /* =(float)(-NLACHANNEL_HEIGHT(snla)) */ /* UNUSED */, ymax=0; /* convert border-region to view coordinates */ UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin+2, &rectf.xmin, &rectf.ymin); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 0d2ec7c646f..9ea1e8ee877 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -305,7 +305,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA if(_sample_col) { cumap->flag |= CUMA_DRAW_SAMPLE; - VECCOPY(cumap->sample, _sample_col); + copy_v3_v3(cumap->sample, _sample_col); } else cumap->flag &= ~CUMA_DRAW_SAMPLE; @@ -639,7 +639,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt float colw= 0.6f*node_group_frame; float col1= 6 - node_group_frame; float col2= col1 + colw+6; - float col3= node_group_frame - arrowbutw - 6; + float col3= - arrowbutw - 6; /* layout stuff for buttons on group right frame */ float cor1= 6; float cor2= cor1 + arrowbutw + 6; @@ -660,6 +660,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt * 1) input: not internal * 2) output: (node type uses const outputs) and (group output is unlinked) */ + draw_value = 0; switch (in_out) { case SOCK_IN: draw_value = !(gsock && (gsock->flag & SOCK_INTERNAL)); @@ -667,8 +668,6 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt case SOCK_OUT: if (gnode->typeinfo->flag & NODE_CONST_OUTPUT) draw_value = !(gsock && gsock->link); - else - draw_value = 0; break; } if (draw_value) { @@ -713,7 +712,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt uiBlockSetDirection(gnode->block, 0); /* remove button */ - offset = (in_out==SOCK_IN ? col3 : col1); + offset = (in_out==SOCK_IN ? col3 : cor1); uiBlockSetEmboss(gnode->block, UI_EMBOSSN); bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, gsock->locx+offset, gsock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); @@ -742,23 +741,23 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* backdrop header */ glEnable(GL_BLEND); - uiSetRoundBox(3); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymax, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); /* backdrop body */ UI_ThemeColorShadeAlpha(TH_BACK, -8, -70); - uiSetRoundBox(0); + uiSetRoundBox(UI_CNR_NONE); uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, BASIS_RAD); /* input column */ UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); - uiSetRoundBox(8); + uiSetRoundBox(UI_CNR_BOTTOM_LEFT); uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymin, rect.xmin, rect.ymax, BASIS_RAD); /* output column */ UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); - uiSetRoundBox(4); + uiSetRoundBox(UI_CNR_BOTTOM_RIGHT); uiDrawBox(GL_POLYGON, rect.xmax, rect.ymin, rect.xmax+node_group_frame, rect.ymax, BASIS_RAD); /* input column separator */ @@ -776,7 +775,7 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN glEnd(); /* group node outline */ - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); glColor4ub(200, 200, 200, 140); glEnable( GL_LINE_SMOOTH ); uiDrawBox(GL_LINE_LOOP, rect.xmin-node_group_frame, rect.ymin, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 6be8978cb5b..c1b114d5436 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -220,7 +220,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) PointerRNA ptr; bNodeSocket *nsock; float locx, locy; - float dy= locy; + float dy; int buty; /* get "global" coords */ @@ -568,7 +568,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN return; } - uiSetRoundBox(15-4); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_LEFT); ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT); /* header */ @@ -580,7 +580,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN if(node->flag & NODE_MUTED) UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f); - uiSetRoundBox(3); + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); /* show/hide icons, note this sequence is copied in do_header_node() node_state.c */ @@ -648,7 +648,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* body */ UI_ThemeColor4(TH_NODE); glEnable(GL_BLEND); - uiSetRoundBox(8); + uiSetRoundBox(UI_CNR_BOTTOM_LEFT); uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax-NODE_DY, BASIS_RAD); glDisable(GL_BLEND); @@ -664,7 +664,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40); else UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120); - uiSetRoundBox(15-4); // round all corners except lower right + uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_LEFT); // round all corners except lower right uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); glDisable( GL_LINE_SMOOTH ); @@ -745,7 +745,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b char showname[128]; /* 128 is used below */ /* shadow */ - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); ui_dropshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT); /* body */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index b5633d50997..5f58f540aae 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -447,9 +447,8 @@ void snode_set_context(SpaceNode *snode, Scene *scene) else if(snode->treetype==NTREE_COMPOSIT) { snode->id= &scene->id; - /* bit clumsy but reliable way to see if we draw first time */ - if(snode->nodetree==NULL) - ntreeCompositForceHidden(scene->nodetree, scene); + /* update output sockets based on available layers */ + ntreeCompositForceHidden(scene->nodetree, scene); } else if(snode->treetype==NTREE_TEXTURE) { Tex *tx= NULL; @@ -608,28 +607,45 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) static int compare_nodes(bNode *a, bNode *b) { bNode *parent; + /* These tell if either the node or any of the parent nodes is selected. + * A selected parent means an unselected node is also in foreground! + */ + int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT); + int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE); /* if one is an ancestor of the other */ /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */ for (parent = a->parent; parent; parent=parent->parent) { + /* if b is an ancestor, it is always behind a */ if (parent==b) return 1; + /* any selected ancestor moves the node forward */ + if (parent->flag & NODE_ACTIVE) + a_active = 1; + if (parent->flag & NODE_SELECT) + a_select = 1; } for (parent = b->parent; parent; parent=parent->parent) { + /* if a is an ancestor, it is always behind b */ if (parent==a) return 0; + /* any selected ancestor moves the node forward */ + if (parent->flag & NODE_ACTIVE) + b_active = 1; + if (parent->flag & NODE_SELECT) + b_select = 1; } /* if one of the nodes is in the background and the other not */ - if ((a->flag & NODE_BACKGROUND) && !(b->typeinfo->flag & NODE_BACKGROUND)) + if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND)) return 0; - else if (!(a->flag & NODE_BACKGROUND) && (b->typeinfo->flag & NODE_BACKGROUND)) + else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND)) return 1; /* if one has a higher selection state (active > selected > nothing) */ - if (!(b->flag & NODE_ACTIVE) && (a->flag & NODE_ACTIVE)) + if (!b_active && a_active) return 1; - else if (!(b->flag & NODE_SELECT) && ((a->flag & NODE_ACTIVE) || (a->flag & NODE_SELECT))) + else if (!b_select && (a_active || a_select)) return 1; return 0; @@ -776,7 +792,7 @@ static int edit_node_invoke_properties(bContext *C, wmOperator *op) static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out) { bNode *node; - bNodeSocket *sock; + bNodeSocket *sock=NULL; char nodename[32]; int sockindex; int in_out; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 95a315272b9..357730aff39 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -97,7 +97,7 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h) TreeElement *te= lb->first; while(te) { TreeStoreElem *tselem= TREESTORE(te); - if((tselem->flag & TSE_CLOSED)==0) + if(TSELEM_OPEN(tselem,soops)) outliner_height(soops, &te->subtree, h); (*h) += UI_UNIT_Y; te= te->next; @@ -112,7 +112,7 @@ static void outliner_width(SpaceOops *soops, ListBase *lb, int *w) // TreeStoreElem *tselem= TREESTORE(te); // XXX fixme... te->xend is not set yet - if(tselem->flag & TSE_CLOSED) { + if(!TSELEM_OPEN(tselem,soops)) { if (te->xend > *w) *w = te->xend; } @@ -135,7 +135,7 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start if(startx+100 > *w) *w = startx+100; - if((tselem->flag & TSE_CLOSED)==0) + if(TSELEM_OPEN(tselem,soops)) outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X); te= te->next; } @@ -519,7 +519,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar } } - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree); + if(TSELEM_OPEN(tselem,soops)) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree); } } @@ -560,7 +560,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa ptr= &te->rnaptr; prop= te->directdata; - if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0)) + if(!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem,soops))) ) uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); } else if(tselem->type == TSE_RNA_ARRAY_ELEM) { @@ -571,7 +571,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa } } - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree); + if(TSELEM_OPEN(tselem,soops)) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree); } } @@ -828,7 +828,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo } } - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree); + if(TSELEM_OPEN(tselem,soops)) outliner_draw_keymapbuts(block, ar, soops, &te->subtree); } } @@ -871,7 +871,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa } } - if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(C, block, ar, soops, &te->subtree); + if(TSELEM_OPEN(tselem,soops)) outliner_buttons(C, block, ar, soops, &te->subtree); } } @@ -1182,7 +1182,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa if(active) { float ufac= UI_UNIT_X/20.0f; - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); glColor4ub(255, 255, 255, 100); uiRoundBox( (float)*offsx-0.5f*ufac, (float)ys-1.0f*ufac, (float)*offsx+UI_UNIT_Y-3.0f*ufac, (float)ys+UI_UNIT_Y-3.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); glEnable(GL_BLEND); /* roundbox disables */ @@ -1237,6 +1237,18 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene glEnable(GL_BLEND); + /* start by highlighting search matches + * we don't expand items when searching in the datablocks but we + * still want to highlight any filter matches. + */ + if ( (SEARCHING_OUTLINER(soops) || (soops->outlinevis==SO_DATABLOCKS && soops->search_string[0]!=0)) && + (tselem->flag & TSE_SEARCHMATCH)) + { + /* TODO - add search highlight colour to theme? */ + glColor4f(0.2f, 0.5f, 0.2f, 0.3f); + glRecti(startx, *starty+1, ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); + } + /* colors for active/selected data */ if(tselem->type==0) { if(te->idcode==ID_SCE) { @@ -1301,7 +1313,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* active circle */ if(active) { - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiRoundBox( (float)startx+UI_UNIT_Y-1.5f*ufac, (float)*starty+2.0f*ufac, (float)startx+2.0f*UI_UNIT_Y-4.0f*ufac, (float)*starty+UI_UNIT_Y-1.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); glEnable(GL_BLEND); /* roundbox disables it */ @@ -1317,10 +1329,10 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene icon_x = startx+5*ufac; // icons a bit higher - if(tselem->flag & TSE_CLOSED) - UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT); - else + if(TSELEM_OPEN(tselem,soops)) UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN); + else + UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT); } offsx+= UI_UNIT_X; @@ -1356,7 +1368,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name)); /* closed item, we draw the icons, not when it's a scene, or master-server list though */ - if(tselem->flag & TSE_CLOSED) { + if(!TSELEM_OPEN(tselem,soops)) { if(te->subtree.first) { if(tselem->type==0 && te->idcode==ID_SCE); else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */ @@ -1382,7 +1394,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene te->ys= (float)*starty; te->xend= startx+offsx; - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { *starty-= UI_UNIT_Y; for(ten= te->subtree.first; ten; ten= ten->next) @@ -1415,7 +1427,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, *starty-= UI_UNIT_Y; - if((tselem->flag & TSE_CLOSED)==0) + if(TSELEM_OPEN(tselem,soops)) outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty); } @@ -1439,12 +1451,12 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase * tselem= TREESTORE(te); /* selection status */ - if((tselem->flag & TSE_CLOSED)==0) + if(TSELEM_OPEN(tselem,soops)) if(tselem->type == TSE_RNA_STRUCT) glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1); *starty-= UI_UNIT_Y; - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { outliner_draw_struct_marks(ar, soops, &te->subtree, starty); if(tselem->type == TSE_RNA_STRUCT) fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y); @@ -1465,7 +1477,7 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); } *starty-= UI_UNIT_Y; - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty); + if(TSELEM_OPEN(tselem,soops)) outliner_draw_selection(ar, soops, &te->subtree, starty); } } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 2b451a48748..05eace0d4ef 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -687,7 +687,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, te->ys= (float)(*starty); *starty-= UI_UNIT_Y; - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { TreeElement *ten; for(ten= te->subtree.first; ten; ten= ten->next) { outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty); @@ -910,7 +910,7 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase } else tselem->flag |= TSE_CLOSED; - if(tselem->flag & TSE_CLOSED); else tree_element_show_hierarchy(scene, soops, &te->subtree); + if(TSELEM_OPEN(tselem,soops)) tree_element_show_hierarchy(scene, soops, &te->subtree); } } @@ -1175,7 +1175,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL } /* go over sub-tree */ - if ((tselem->flag & TSE_CLOSED)==0) + if (TSELEM_OPEN(tselem,soops)) do_outliner_drivers_editop(soops, &te->subtree, reports, mode); } } @@ -1343,7 +1343,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa } /* go over sub-tree */ - if ((tselem->flag & TSE_CLOSED)==0) + if (TSELEM_OPEN(tselem,soops)) do_outliner_keyingset_editop(soops, ks, &te->subtree, mode); } } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 61507d1ffe5..215ab508ab6 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -126,6 +126,27 @@ typedef struct TreeElement { #define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5f) +/* Outliner Searching -- + + Are we looking for something in the outliner? + If so finding matches in child items makes it more useful + + - We want to flag parents to act as being open to filter child matches + - and also flag matches so we can highlight them + - Flags are stored in TreeStoreElem->flag + - Flag options defined in DNA_outliner_types.h + - SO_SEARCH_RECURSIVE defined in DNA_space_types.h + + - NOT in datablocks view - searching all datablocks takes way too long + to be useful + - not searching into RNA items helps but isn't the complete solution + */ + +#define SEARCHING_OUTLINER(sov) (sov->search_flags & SO_SEARCH_RECURSIVE) + +/* is the currrent element open? if so we also show children */ +#define TSELEM_OPEN(telm,sv) ( (telm->flag & TSE_CLOSED)==0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH)) ) + /* outliner_tree.c ----------------------------------------------- */ void outliner_free_tree(ListBase *lb); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 2c0a8c34747..a88625aad0d 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -134,7 +134,7 @@ static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *se change |= 1; } } - else if ((tselem->flag & TSE_CLOSED)==0) { + else if (TSELEM_OPEN(tselem,soops)) { /* Only try selecting sub-elements if we haven't hit the right element yet * * Hack warning: diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index b3170f9cd1e..b2fdd34aab2 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -145,7 +145,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb, } } } - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { set_operation_types(soops, &te->subtree, scenelevel, objectlevel, idlevel, datalevel); } @@ -250,7 +250,7 @@ static void outliner_do_libdata_operation(bContext *C, Scene *scene, SpaceOops * operation_cb(C, scene, te, tsep, tselem); } } - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb); } } @@ -397,7 +397,7 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem); } } - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb); } } @@ -504,7 +504,7 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li operation_cb(event, te, tselem); } } - if((tselem->flag & TSE_CLOSED)==0) { + if(TSELEM_OPEN(tselem,soops)) { outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb); } } @@ -857,7 +857,7 @@ static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase *l operation_cb(te, tselem, tsep, newid); } } - if ((tselem->flag & TSE_CLOSED)==0) { + if (TSELEM_OPEN(tselem,soops)) { outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb); } } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 8904dcc360f..7e9eabc08db 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -827,6 +827,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i check_persistant(soops, te, id, type, index); tselem= TREESTORE(te); + /* if we are searching for something expand to see child elements */ + if(SEARCHING_OUTLINER(soops)) + tselem->flag |= TSE_CHILDSEARCH; + te->parent= parent; te->index= index; // for data arays if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)); @@ -981,6 +985,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else te->name= (char*)RNA_struct_ui_name(ptr->type); + /* If searching don't expand RNA entries */ + if(SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH; + iterprop= RNA_struct_iterator_property(ptr->type); tot= RNA_property_collection_length(ptr, iterprop); @@ -989,7 +996,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if(!tselem->used) tselem->flag &= ~TSE_CLOSED; - if(!(tselem->flag & TSE_CLOSED)) { + if(TSELEM_OPEN(tselem,soops)) { for(a=0; a<tot; a++) outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a); } @@ -1010,11 +1017,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->directdata= prop; te->rnaptr= *ptr; + /* If searching don't expand RNA entries */ + if(SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH; + if(proptype == PROP_POINTER) { pptr= RNA_property_pointer_get(ptr, prop); if(pptr.data) { - if(!(tselem->flag & TSE_CLOSED)) + if(TSELEM_OPEN(tselem,soops)) outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1); else te->flag |= TE_LAZY_CLOSED; @@ -1023,7 +1033,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if(proptype == PROP_COLLECTION) { tot= RNA_property_collection_length(ptr, prop); - if(!(tselem->flag & TSE_CLOSED)) { + if(TSELEM_OPEN(tselem,soops)) { for(a=0; a<tot; a++) { RNA_property_collection_lookup_int(ptr, prop, a, &pptr); outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, a); @@ -1035,7 +1045,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) { tot= RNA_property_array_length(ptr, prop); - if(!(tselem->flag & TSE_CLOSED)) { + if(TSELEM_OPEN(tselem,soops)) { for(a=0; a<tot; a++) outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a); } @@ -1068,7 +1078,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->directdata= idv; te->name= km->idname; - if(!(tselem->flag & TSE_CLOSED)) { + if(TSELEM_OPEN(tselem,soops)) { a= 0; for (kmi= km->items.first; kmi; kmi= kmi->next, a++) { @@ -1368,7 +1378,10 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb) */ tselem= TREESTORE(te); - if ((tselem->flag & TSE_CLOSED) || outliner_filter_tree(soops, &te->subtree)==0) { + /* flag as not a found item */ + tselem->flag &= ~TSE_SEARCHMATCH; + + if ((!TSELEM_OPEN(tselem,soops)) || outliner_filter_tree(soops, &te->subtree)==0) { outliner_free_tree(&te->subtree); BLI_remlink(lb, te); @@ -1377,6 +1390,11 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb) } } else { + tselem= TREESTORE(te); + + /* flag as a found item - we can then highlight it */ + tselem->flag |= TSE_SEARCHMATCH; + /* filter subtree too */ outliner_filter_tree(soops, &te->subtree); } @@ -1399,6 +1417,14 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) TreeStoreElem *tselem; int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */ + /* Are we looking for something - we want to tag parents to filter child matches + - NOT in datablocks view - searching all datablocks takes way too long to be useful + - this variable is only set once per tree build */ + if(soops->search_string[0]!=0 && soops->outlinevis!=SO_DATABLOCKS) + soops->search_flags |= SO_SEARCH_RECURSIVE; + else + soops->search_flags &= ~SO_SEARCH_RECURSIVE; + if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW)) return; diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 299fe9df460..0f5398f24a7 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -99,7 +99,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ UI_GetThemeColor3ubv(TH_SEQ_SCENE, col); if(seq->scene==curscene) { - UI_GetColorPtrBlendShade3ubv(col, col, col, 1.0, 20); + UI_GetColorPtrShade3ubv(col, col, 20); } break; @@ -299,7 +299,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, glRectf(x1_chan, y1_chan, x2_chan, y2_chan); - UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -30); + UI_GetColorPtrShade3ubv(col, col, -30); glColor4ubv(col); fdrawbox(x1_chan, y1_chan, x2_chan, y2_chan); @@ -473,7 +473,7 @@ static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq) /* feint pinstripes, helps see exactly which is extended and which isn't, * especially when the extension is very small */ if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24); - else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16); + else UI_GetColorPtrShade3ubv(col, col, -16); glColor3ubv((GLubyte *)col); @@ -490,8 +490,8 @@ static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq) /* feint pinstripes, helps see exactly which is extended and which isn't, * especially when the extension is very small */ - if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24); - else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16); + if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24); + else UI_GetColorPtrShade3ubv(col, col, -16); glColor3ubv((GLubyte *)col); @@ -584,8 +584,8 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa glBegin(GL_QUADS); if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; } - else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50); - else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0); + else if(seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, -50); + /* else UI_GetColorPtrShade3ubv(col, col, 0); */ /* DO NOTHING */ glColor3ubv(col); @@ -594,7 +594,7 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; } else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5); - else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5); + else UI_GetColorPtrShade3ubv(col, col, -5); glColor3ubv((GLubyte *)col); @@ -610,8 +610,8 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa glVertex2f(x1,ymid2); glVertex2f(x2,ymid2); - if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -15); - else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 25); + if(seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, -15); + else UI_GetColorPtrShade3ubv(col, col, 25); glColor3ubv((GLubyte *)col); @@ -697,10 +697,10 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline col[0]= 255; col[1]= col[2]= 40; } else - UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120+outline_tint); + UI_GetColorPtrShade3ubv(col, col, 120+outline_tint); } else - UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint); + UI_GetColorPtrShade3ubv(col, col, outline_tint); glColor3ubv((GLubyte *)col); @@ -914,7 +914,7 @@ void draw_image_seq(const bContext* C, Scene *scene, ARegion *ar, SpaceSeq *sseq glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 066404f23ba..3d49bc7ffa0 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1190,7 +1190,7 @@ static void draw_textscroll(SpaceText *st, rcti *scroll, rcti *back) uiWidgetScrollDraw(&wcol, scroll, &st->txtbar, (st->flags & ST_SCROLL_SELECT)?UI_SCROLL_PRESSED:0); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); rad= 0.4f*MIN2(st->txtscroll.xmax - st->txtscroll.xmin, st->txtscroll.ymax - st->txtscroll.ymin); UI_GetThemeColor3ubv(TH_HILITE, col); col[3]= 48; diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index ecf5df4af7c..fc35ab93f70 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -85,7 +85,7 @@ enum { PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */ PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */ PCHAN_COLOR_LINEBONE /* for the middle of line-bones */ -}; +}; /* This function sets the color-set for coloring a certain bone */ static void set_pchan_colorset (Object *ob, bPoseChannel *pchan) @@ -437,43 +437,64 @@ static void draw_bonevert_solid(void) glCallList(displist); } +static float bone_octahedral_verts[6][3]= { + { 0.0f, 0.0f, 0.0f}, + { 0.1f, 0.1f, 0.1f}, + { 0.1f, 0.1f, -0.1f}, + {-0.1f, 0.1f, -0.1f}, + {-0.1f, 0.1f, 0.1f}, + { 0.0f, 1.0f, 0.0f} +}; + +static unsigned int bone_octahedral_wire_sides[8]= {0, 1, 5, 3, 0, 4, 5, 2}; +static unsigned int bone_octahedral_wire_square[8]= {1, 2, 3, 4, 1}; + +static unsigned int bone_octahedral_solid_tris[8][3]= { + {2, 1, 0}, /* bottom */ + {3, 2, 0}, + {4, 3, 0}, + {1, 4, 0}, + + {5, 1, 2}, /* top */ + {5, 2, 3}, + {5, 3, 4}, + {5, 4, 1} +}; + +/* aligned with bone_octahedral_solid_tris */ +static float bone_octahedral_solid_normals[8][3]= { + { 0.70710683f, -0.70710683f, 0.00000000f}, + {-0.00000000f, -0.70710683f, -0.70710683f}, + {-0.70710683f, -0.70710683f, 0.00000000f}, + { 0.00000000f, -0.70710683f, 0.70710683f}, + { 0.99388373f, 0.11043154f, -0.00000000f}, + { 0.00000000f, 0.11043154f, -0.99388373f}, + {-0.99388373f, 0.11043154f, 0.00000000f}, + { 0.00000000f, 0.11043154f, 0.99388373f} +}; + static void draw_bone_octahedral(void) { static GLuint displist=0; if (displist == 0) { - float vec[6][3]; - displist= glGenLists(1); glNewList(displist, GL_COMPILE); - - vec[0][0]= vec[0][1]= vec[0][2]= 0.0f; - vec[5][0]= vec[5][2]= 0.0f; vec[5][1]= 1.0f; - - vec[1][0]= 0.1f; vec[1][2]= 0.1f; vec[1][1]= 0.1f; - vec[2][0]= 0.1f; vec[2][2]= -0.1f; vec[2][1]= 0.1f; - vec[3][0]= -0.1f; vec[3][2]= -0.1f; vec[3][1]= 0.1f; - vec[4][0]= -0.1f; vec[4][2]= 0.1f; vec[4][1]= 0.1f; - + /* Section 1, sides */ - glBegin(GL_LINE_LOOP); - glVertex3fv(vec[0]); - glVertex3fv(vec[1]); - glVertex3fv(vec[5]); - glVertex3fv(vec[3]); - glVertex3fv(vec[0]); - glVertex3fv(vec[4]); - glVertex3fv(vec[5]); - glVertex3fv(vec[2]); - glEnd(); - + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts); + glDrawElements(GL_LINE_LOOP, + sizeof(bone_octahedral_wire_sides)/sizeof(*bone_octahedral_wire_sides), + GL_UNSIGNED_INT, + bone_octahedral_wire_sides); + /* Section 1, square */ - glBegin(GL_LINE_LOOP); - glVertex3fv(vec[1]); - glVertex3fv(vec[2]); - glVertex3fv(vec[3]); - glVertex3fv(vec[4]); - glEnd(); + glDrawElements(GL_LINE_LOOP, + sizeof(bone_octahedral_wire_square)/sizeof(*bone_octahedral_wire_square), + GL_UNSIGNED_INT, + bone_octahedral_wire_square); + glDisableClientState(GL_VERTEX_ARRAY); glEndList(); } @@ -484,59 +505,34 @@ static void draw_bone_octahedral(void) static void draw_bone_solid_octahedral(void) { static GLuint displist=0; - + if (displist == 0) { - float vec[6][3], nor[3]; - + int i; + displist= glGenLists(1); glNewList(displist, GL_COMPILE); - - vec[0][0]= vec[0][1]= vec[0][2]= 0.0f; - vec[5][0]= vec[5][2]= 0.0f; vec[5][1]= 1.0f; - - vec[1][0]= 0.1f; vec[1][2]= 0.1f; vec[1][1]= 0.1f; - vec[2][0]= 0.1f; vec[2][2]= -0.1f; vec[2][1]= 0.1f; - vec[3][0]= -0.1f; vec[3][2]= -0.1f; vec[3][1]= 0.1f; - vec[4][0]= -0.1f; vec[4][2]= 0.1f; vec[4][1]= 0.1f; - - - glBegin(GL_TRIANGLES); - /* bottom */ - normal_tri_v3( nor,vec[2], vec[1], vec[0]); - glNormal3fv(nor); - glVertex3fv(vec[2]); glVertex3fv(vec[1]); glVertex3fv(vec[0]); - - normal_tri_v3( nor,vec[3], vec[2], vec[0]); - glNormal3fv(nor); - glVertex3fv(vec[3]); glVertex3fv(vec[2]); glVertex3fv(vec[0]); - - normal_tri_v3( nor,vec[4], vec[3], vec[0]); - glNormal3fv(nor); - glVertex3fv(vec[4]); glVertex3fv(vec[3]); glVertex3fv(vec[0]); - normal_tri_v3( nor,vec[1], vec[4], vec[0]); - glNormal3fv(nor); - glVertex3fv(vec[1]); glVertex3fv(vec[4]); glVertex3fv(vec[0]); +#if 1 + glBegin(GL_TRIANGLES); + for(i= 0; i < 8; i++) { + glNormal3fv(bone_octahedral_solid_normals[i]); + glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][0]]); + glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][1]]); + glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]); + } - /* top */ - normal_tri_v3( nor,vec[5], vec[1], vec[2]); - glNormal3fv(nor); - glVertex3fv(vec[5]); glVertex3fv(vec[1]); glVertex3fv(vec[2]); - - normal_tri_v3( nor,vec[5], vec[2], vec[3]); - glNormal3fv(nor); - glVertex3fv(vec[5]); glVertex3fv(vec[2]); glVertex3fv(vec[3]); - - normal_tri_v3( nor,vec[5], vec[3], vec[4]); - glNormal3fv(nor); - glVertex3fv(vec[5]); glVertex3fv(vec[3]); glVertex3fv(vec[4]); - - normal_tri_v3( nor,vec[5], vec[4], vec[1]); - glNormal3fv(nor); - glVertex3fv(vec[5]); glVertex3fv(vec[4]); glVertex3fv(vec[1]); - glEnd(); - + +#else /* not working because each vert needs a different normal */ + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glNormalPointer(GL_FLOAT, 0, bone_octahedral_solid_normals); + glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts); + glDrawElements(GL_TRIANGLES, sizeof(bone_octahedral_solid_tris)/sizeof(unsigned int), GL_UNSIGNED_INT, bone_octahedral_solid_tris); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); +#endif + glEndList(); } @@ -831,7 +827,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, if (0.0f != normalize_v3(dirvec)) { float norvech[3], norvect[3], vec[3]; - VECCOPY(vec, dirvec); + copy_v3_v3(vec, dirvec); mul_v3_fl(dirvec, head); cross_v3_v3v3(norvech, dirvec, imat[2]); @@ -1548,7 +1544,7 @@ static void draw_pose_dofs(Object *ob) /* in parent-bone pose, but own restspace */ glPushMatrix(); - VECCOPY(posetrans, pchan->pose_mat[3]); + copy_v3_v3(posetrans, pchan->pose_mat[3]); glTranslatef(posetrans[0], posetrans[1], posetrans[2]); if (pchan->parent) { @@ -1646,7 +1642,7 @@ static void bone_matrix_translate_y(float mat[][4], float y) { float trans[3]; - VECCOPY(trans, mat[1]); + copy_v3_v3(trans, mat[1]); mul_v3_fl(trans, y); add_v3_v3(mat[3], trans); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 459a07d03a4..81848b2f0d9 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -139,7 +139,7 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) /* ************* only use while object drawing ************** * or after running ED_view3d_init_mats_rv3d * */ -static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr, int local) +static void view3d_project_short_clip(ARegion *ar, const float vec[3], short *adr, int local) { RegionView3D *rv3d= ar->regiondata; float fx, fy, vec4[4]; @@ -174,7 +174,7 @@ static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr, int l } /* only use while object drawing */ -static void view3d_project_short_noclip(ARegion *ar, float *vec, short *adr) +static void view3d_project_short_noclip(ARegion *ar, const float vec[3], short *adr) { RegionView3D *rv3d= ar->regiondata; float fx, fy, vec4[4]; @@ -837,7 +837,7 @@ static void drawcube_size(float size) /* this is an unused (old) cube-drawing function based on a given size */ #if 0 -static void drawcube_size(float *size) +static void drawcube_size(const float size[3]) { glPushMatrix(); @@ -891,7 +891,7 @@ static void drawshadbuflimits(Lamp *la, float mat[][4]) -static void spotvolume(float *lvec, float *vvec, float inp) +static void spotvolume(float lvec[3], float vvec[3], const float inp) { /* camera is at 0,0,0 */ float temp[3],plane[3],mat1[3][3],mat2[3][3],mat3[3][3],mat4[3][3],q[4],co,si,angle; @@ -920,8 +920,8 @@ static void spotvolume(float *lvec, float *vvec, float inp) normalize_v3(&q[1]); angle = saacos(plane[2])/2.0f; - co = cos(angle); - si = sqrt(1-co*co); + co = cosf(angle); + si = sqrtf(1-co*co); q[0] = co; q[1] *= si; @@ -935,7 +935,7 @@ static void spotvolume(float *lvec, float *vvec, float inp) unit_m3(mat2); co = inp; - si = sqrt(1-inp*inp); + si = sqrtf(1.0f-inp*inp); mat2[0][0] = co; mat2[1][0] = -si; @@ -5079,7 +5079,7 @@ static void draw_textcurs(float textcurs[][2]) set_inverted_drawing(0); } -static void drawspiral(float *cent, float rad, float tmat[][4], int start) +static void drawspiral(const float cent[3], float rad, float tmat[][4], int start) { float vec[3], vx[3], vy[3]; int a, tot=32; @@ -5150,7 +5150,7 @@ static void drawcircle_size(float size) } /* needs fixing if non-identity matrice used */ -static void drawtube(float *vec, float radius, float height, float tmat[][4]) +static void drawtube(const float vec[3], float radius, float height, float tmat[][4]) { float cur[3]; drawcircball(GL_LINE_LOOP, vec, radius, tmat); @@ -5172,7 +5172,7 @@ static void drawtube(float *vec, float radius, float height, float tmat[][4]) glEnd(); } /* needs fixing if non-identity matrice used */ -static void drawcone(float *vec, float radius, float height, float tmat[][4]) +static void drawcone(const float vec[3], float radius, float height, float tmat[][4]) { float cur[3]; @@ -5448,7 +5448,7 @@ static void draw_box(float vec[8][3]) /* uses boundbox, function used by Ketsji */ #if 0 -static void get_local_bounds(Object *ob, float *center, float *size) +static void get_local_bounds(Object *ob, float center[3], float size[3]) { BoundBox *bb= object_get_boundbox(ob); @@ -5885,46 +5885,68 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* which wire color */ if((flag & DRAW_CONSTCOLOR) == 0) { + /* confusing logic here, there are 2 methods of setting the color + * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. + * + * note: no theme yet for 'colindex' */ + int theme_id= TH_WIRE; + int theme_shade= 0; + project_short(ar, ob->obmat[3], &base->sx); - if( (!scene->obedit) && (G.moving & G_TRANSFORM_OBJ) && (base->flag & (SELECT+BA_WAS_SEL))) UI_ThemeColor(TH_TRANSFORM); + if( (scene->obedit == NULL) && + (G.moving & G_TRANSFORM_OBJ) && + (base->flag & (SELECT+BA_WAS_SEL))) + { + theme_id= TH_TRANSFORM; + } else { - - if(ob->type==OB_LAMP) UI_ThemeColor(TH_LAMP); - else if(ob->type==OB_SPEAKER) UI_ThemeColor(TH_SPEAKER); - else UI_ThemeColor(TH_WIRE); - - if((scene->basact)==base) { - if(base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); - } - else { - if(base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_SELECT); - } - - // no theme yet + /* Sets the 'colindex' */ if(ob->id.lib) { - if(base->flag & (SELECT+BA_WAS_SEL)) colindex = 4; - else colindex = 3; + colindex= (base->flag & (SELECT+BA_WAS_SEL)) ? 4 : 3; } else if(warning_recursive==1) { if(base->flag & (SELECT+BA_WAS_SEL)) { - if(scene->basact==base) colindex = 8; - else colindex= 7; + colindex= (scene->basact==base) ? 8 : 7; } - else colindex = 6; - } - else if(ob->flag & OB_FROMGROUP) { - if(base->flag & (SELECT+BA_WAS_SEL)) { - if(scene->basact==base) UI_ThemeColor(TH_GROUP_ACTIVE); - else UI_ThemeColorShade(TH_GROUP_ACTIVE, -16); + else { + colindex = 6; } - else UI_ThemeColor(TH_GROUP); - colindex= 0; } + /* Sets the 'theme_id' or fallback to wire */ + else { + if(ob->flag & OB_FROMGROUP) { + if(base->flag & (SELECT+BA_WAS_SEL)) { + /* uses darker active color for non-active + selected*/ + theme_id= TH_GROUP_ACTIVE; - } + if(scene->basact != base) { + theme_shade= -16; + } + } + else { + theme_id= TH_GROUP; + } + } + else { + if(base->flag & (SELECT+BA_WAS_SEL)) { + theme_id= scene->basact == base ? TH_ACTIVE : TH_SELECT; + } + else { + if(ob->type==OB_LAMP) theme_id= TH_LAMP; + else if(ob->type==OB_SPEAKER) theme_id= TH_SPEAKER; + /* fallback to TH_WIRE */ + } + } + } + } - if(colindex) { + /* finally set the color */ + if(colindex == 0) { + if(theme_shade == 0) UI_ThemeColor(theme_id); + else UI_ThemeColorShade(theme_id, theme_shade); + } + else { col= colortab[colindex]; cpack(col); } @@ -6009,7 +6031,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } if (cu->linewidth != 0.0f) { - cpack(0xff44ff); UI_ThemeColor(TH_WIRE); copy_v3_v3(vec1, ob->orig); copy_v3_v3(vec2, ob->orig); @@ -6028,10 +6049,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) setlinestyle(3); for (i=0; i<cu->totbox; i++) { if (cu->tb[i].w != 0.0f) { - if (i == (cu->actbox-1)) - UI_ThemeColor(TH_ACTIVE); - else - UI_ThemeColor(TH_WIRE); + UI_ThemeColor(i == (cu->actbox-1) ? TH_ACTIVE : TH_WIRE); vec1[0] = (cu->xof * cu->fsize) + cu->tb[i].x; vec1[1] = (cu->yof * cu->fsize) + cu->tb[i].y + cu->fsize; vec1[2] = 0.001; diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index acdbcb0d06d..8da6f49e089 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -154,10 +154,10 @@ static int convex(float *p0, float *up, float *a, float *b) { // Vec3 va = a-p0, vb = b-p0; float va[3], vb[3], tmp[3]; - VECSUB(va, a, p0); - VECSUB(vb, b, p0); + sub_v3_v3v3(va, a, p0); + sub_v3_v3v3(vb, b, p0); cross_v3_v3v3(tmp, va, vb); - return INPR(up, tmp) >= 0; + return dot_v3v3(up, tmp) >= 0; } // copied from gpu_extension.c @@ -280,20 +280,20 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 cv[7][1] = min[1]; cv[7][2] = min[2]; - VECCOPY(edges[0][0], cv[4]); // maxx, maxy, minz - VECCOPY(edges[1][0], cv[5]); // minx, maxy, minz - VECCOPY(edges[2][0], cv[6]); // minx, miny, minz - VECCOPY(edges[3][0], cv[7]); // maxx, miny, minz + copy_v3_v3(edges[0][0], cv[4]); // maxx, maxy, minz + copy_v3_v3(edges[1][0], cv[5]); // minx, maxy, minz + copy_v3_v3(edges[2][0], cv[6]); // minx, miny, minz + copy_v3_v3(edges[3][0], cv[7]); // maxx, miny, minz - VECCOPY(edges[4][0], cv[3]); // maxx, miny, maxz - VECCOPY(edges[5][0], cv[2]); // minx, miny, maxz - VECCOPY(edges[6][0], cv[6]); // minx, miny, minz - VECCOPY(edges[7][0], cv[7]); // maxx, miny, minz + copy_v3_v3(edges[4][0], cv[3]); // maxx, miny, maxz + copy_v3_v3(edges[5][0], cv[2]); // minx, miny, maxz + copy_v3_v3(edges[6][0], cv[6]); // minx, miny, minz + copy_v3_v3(edges[7][0], cv[7]); // maxx, miny, minz - VECCOPY(edges[8][0], cv[1]); // minx, maxy, maxz - VECCOPY(edges[9][0], cv[2]); // minx, miny, maxz - VECCOPY(edges[10][0], cv[6]); // minx, miny, minz - VECCOPY(edges[11][0], cv[5]); // minx, maxy, minz + copy_v3_v3(edges[8][0], cv[1]); // minx, maxy, maxz + copy_v3_v3(edges[9][0], cv[2]); // minx, miny, maxz + copy_v3_v3(edges[10][0], cv[6]); // minx, miny, minz + copy_v3_v3(edges[11][0], cv[5]); // minx, maxy, minz // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); // printf("min[2]: %f, max[2]: %f\n", min[2], max[2]); @@ -332,7 +332,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 */ // get view vector - VECCOPY(viewnormal, rv3d->viewinv[2]); + copy_v3_v3(viewnormal, rv3d->viewinv[2]); normalize_v3(viewnormal); // find cube vertex that is closest to the viewer @@ -407,10 +407,10 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 if(dd*(float)n > ds) break; - VECCOPY(tmp_point, viewnormal); + copy_v3_v3(tmp_point, viewnormal); mul_v3_fl(tmp_point, -dd*((ds/dd)-(float)n)); - VECADD(tmp_point2, cv[good_index], tmp_point); - d = INPR(tmp_point2, viewnormal); + add_v3_v3v3(tmp_point2, cv[good_index], tmp_point); + d = dot_v3v3(tmp_point2, viewnormal); // printf("my d: %f\n", d); @@ -421,7 +421,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 // printf("points: %d\n", numpoints); if (numpoints > 2) { - VECCOPY(p0, points); + copy_v3_v3(p0, points); // sort points to get a convex polygon for(i = 1; i < numpoints - 1; i++) @@ -431,9 +431,9 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 if(!convex(p0, viewnormal, &points[j * 3], &points[i * 3])) { float tmp2[3]; - VECCOPY(tmp2, &points[j * 3]); - VECCOPY(&points[j * 3], &points[i * 3]); - VECCOPY(&points[i * 3], tmp2); + copy_v3_v3(tmp2, &points[j * 3]); + copy_v3_v3(&points[j * 3], &points[i * 3]); + copy_v3_v3(&points[i * 3], tmp2); } } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 98768e369cb..ba9faf7682e 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -150,20 +150,22 @@ void circ(float x, float y, float rad) static void view3d_draw_clipping(RegionView3D *rv3d) { BoundBox *bb= rv3d->clipbb; - + if(bb) { + static unsigned int clipping_index[6][4]= {{0, 1, 2, 3}, + {0, 4, 5, 1}, + {4, 7, 6, 5}, + {7, 3, 2, 6}, + {1, 5, 6, 2}, + {7, 4, 0, 3}}; + UI_ThemeColorShade(TH_BACK, -8); - - glBegin(GL_QUADS); - - glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[3]); - glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[1]); - glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[5]); - glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[3]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[6]); - glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[2]); - glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[3]); - - glEnd(); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, bb->vec); + glDrawElements(GL_QUADS, sizeof(clipping_index)/sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index); + glDisableClientState(GL_VERTEX_ARRAY); + } } @@ -194,11 +196,11 @@ static int test_clipping(const float vec[3], float clip[][4]) { float view[3]; copy_v3_v3(view, vec); - - if(0.0f < clip[0][3] + INPR(view, clip[0])) - if(0.0f < clip[1][3] + INPR(view, clip[1])) - if(0.0f < clip[2][3] + INPR(view, clip[2])) - if(0.0f < clip[3][3] + INPR(view, clip[3])) + + if(0.0f < clip[0][3] + dot_v3v3(view, clip[0])) + if(0.0f < clip[1][3] + dot_v3v3(view, clip[1])) + if(0.0f < clip[2][3] + dot_v3v3(view, clip[2])) + if(0.0f < clip[3][3] + dot_v3v3(view, clip[3])) return 0; return 1; @@ -216,36 +218,37 @@ int ED_view3d_test_clipping(RegionView3D *rv3d, const float vec[3], const int lo static void drawgrid_draw(ARegion *ar, float wx, float wy, float x, float y, float dx) { - float v1[2], v2[2]; + float verts[2][2]; x+= (wx); y+= (wy); - v1[1]= 0.0f; - v2[1]= (float)ar->winy; + /* set fixed 'Y' */ + verts[0][1]= 0.0f; + verts[1][1]= (float)ar->winy; - v1[0] = v2[0] = x-dx*floorf(x/dx); - - glBegin(GL_LINES); - - while(v1[0] < ar->winx) { - glVertex2fv(v1); - glVertex2fv(v2); - v1[0] = v2[0] = v1[0] + dx; - } + /* iter over 'X' */ + verts[0][0] = verts[1][0] = x-dx*floorf(x/dx); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, verts); - v1[0]= 0.0f; - v2[0]= (float)ar->winx; + while(verts[0][0] < ar->winx) { + glDrawArrays(GL_LINES, 0, 2); + verts[0][0] = verts[1][0] = verts[0][0] + dx; + } - v1[1]= v2[1]= y-dx*floorf(y/dx); + /* set fixed 'X' */ + verts[0][0]= 0.0f; + verts[1][0]= (float)ar->winx; - while(v1[1] < ar->winy) { - glVertex2fv(v1); - glVertex2fv(v2); - v1[1] = v2[1] = v1[1] + dx; + /* iter over 'Y' */ + verts[0][1]= verts[1][1]= y-dx*floorf(y/dx); + while(verts[0][1] < ar->winy) { + glDrawArrays(GL_LINES, 0, 2); + verts[0][1] = verts[1][1] = verts[0][1] + dx; } - glEnd(); + glDisableClientState(GL_VERTEX_ARRAY); } #define GRID_MIN_PX 6.0f @@ -425,13 +428,10 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) { - float vert[3], grid, grid_scale; - int a, gridlines, emphasise; - unsigned char col[3], col2[3]; - short draw_line = 0; - - vert[2]= 0.0; - + float grid, grid_scale; + unsigned char col_grid[3]; + const int gridlines= v3d->gridlines/2; + if(v3d->gridlines<3) return; grid_scale= v3d->grid; @@ -450,115 +450,81 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) grid_scale = (grid_scale * (float)bUnit_GetScaler(usys, i)) / scene->unit.scale_length; } } - - if(v3d->zbuf && scene->obedit) glDepthMask(0); // for zbuffer-select - - gridlines= v3d->gridlines/2; + grid= gridlines * grid_scale; - UI_GetThemeColor3ubv(TH_GRID, col); - UI_GetThemeColor3ubv(TH_BACK, col2); - - /* emphasise division lines lighter instead of darker, if background is darker than grid */ - if ( ((col[0]+col[1]+col[2])/3+10) > (col2[0]+col2[1]+col2[2])/3 ) - emphasise = 20; - else - emphasise = -10; - + if(v3d->zbuf && scene->obedit) glDepthMask(0); // for zbuffer-select + + UI_GetThemeColor3ubv(TH_GRID, col_grid); + /* draw the Y axis and/or grid lines */ - for(a= -gridlines;a<=gridlines;a++) { - if(a==0) { - /* check for the 'show Y axis' preference */ - if (v3d->gridflag & V3D_SHOW_Y) { - UI_make_axis_color(col, col2, 'Y'); - glColor3ubv(col2); - - draw_line = 1; - } else if (v3d->gridflag & V3D_SHOW_FLOOR) { - UI_ThemeColorShade(TH_GRID, emphasise); - } else { - draw_line = 0; + if(v3d->gridflag & V3D_SHOW_FLOOR) { + float vert[4][3]= {{0.0f}}; + unsigned char col_bg[3]; + unsigned char col_grid_emphasise[3], col_grid_light[3]; + int a; + int prev_emphasise= -1; + + UI_GetThemeColor3ubv(TH_BACK, col_bg); + + /* emphasise division lines lighter instead of darker, if background is darker than grid */ + UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10); + UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise, + (((col_grid[0]+col_grid[1]+col_grid[2])+30) > (col_bg[0]+col_bg[1]+col_bg[2])) ? 20 : -10); + + /* set fixed axis */ + vert[0][0]= vert[2][1]= grid; + vert[1][0]= vert[3][1]= -grid; + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vert); + + for(a= -gridlines;a<=gridlines;a++) { + const float line= a * grid_scale; + const int is_emphasise= (a % 10) == 0; + + if(is_emphasise != prev_emphasise) { + glColor3ubv(is_emphasise ? col_grid_emphasise : col_grid_light); + prev_emphasise= is_emphasise; } - } else { - /* check for the 'show grid floor' preference */ - if (v3d->gridflag & V3D_SHOW_FLOOR) { - if( (a % 10)==0) { - UI_ThemeColorShade(TH_GRID, emphasise); - } - else UI_ThemeColorShade(TH_GRID, 10); - - draw_line = 1; - } else { - draw_line = 0; - } - } - - if (draw_line) { - glBegin(GL_LINE_STRIP); - vert[0]= a * grid_scale; - vert[1]= grid; - glVertex3fv(vert); - vert[1]= -grid; - glVertex3fv(vert); - glEnd(); + + /* set variable axis */ + vert[0][1]= vert[1][1]= + vert[2][0]= vert[3][0]= line; + + glDrawArrays(GL_LINES, 0, 4); } + + glDisableClientState(GL_VERTEX_ARRAY); + + GPU_print_error("sdsd"); } - /* draw the X axis and/or grid lines */ - for(a= -gridlines;a<=gridlines;a++) { - if(a==0) { - /* check for the 'show X axis' preference */ - if (v3d->gridflag & V3D_SHOW_X) { - UI_make_axis_color(col, col2, 'X'); - glColor3ubv(col2); - - draw_line = 1; - } else if (v3d->gridflag & V3D_SHOW_FLOOR) { - UI_ThemeColorShade(TH_GRID, emphasise); - } else { - draw_line = 0; - } - } else { - /* check for the 'show grid floor' preference */ - if (v3d->gridflag & V3D_SHOW_FLOOR) { - if( (a % 10)==0) { - UI_ThemeColorShade(TH_GRID, emphasise); - } - else UI_ThemeColorShade(TH_GRID, 10); - - draw_line = 1; - } else { - draw_line = 0; - } - } - - if (draw_line) { + /* draw the Z axis line */ + /* check for the 'show Z axis' preference */ + if (v3d->gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) { + int axis; + for(axis= 0; axis < 3; axis++) + if (v3d->gridflag & (V3D_SHOW_X << axis)) { + float vert[3]; + unsigned char tcol[3]; + + UI_make_axis_color(col_grid, tcol, 'X' + axis); + glColor3ubv(tcol); + glBegin(GL_LINE_STRIP); - vert[1]= a * grid_scale; - vert[0]= grid; + zero_v3(vert); + vert[axis]= grid; glVertex3fv(vert ); - vert[0]= -grid; + vert[axis]= -grid; glVertex3fv(vert); glEnd(); } } - - /* draw the Z axis line */ - /* check for the 'show Z axis' preference */ - if (v3d->gridflag & V3D_SHOW_Z) { - UI_make_axis_color(col, col2, 'Z'); - glColor3ubv(col2); - - glBegin(GL_LINE_STRIP); - vert[0]= 0; - vert[1]= 0; - vert[2]= grid; - glVertex3fv(vert ); - vert[2]= -grid; - glVertex3fv(vert); - glEnd(); - } - + + + + if(v3d->zbuf && scene->obedit) glDepthMask(1); } @@ -697,60 +663,63 @@ static void draw_rotation_guide(RegionView3D *rv3d) float scaled_axis[3]; const float scale = rv3d->dist; mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale); - + + glBegin(GL_LINE_STRIP); - color[3] = 0.f; // more transparent toward the ends - glColor4fv(color); - add_v3_v3v3(end, o, scaled_axis); - glVertex3fv(end); - - // color[3] = 0.2f + fabsf(rv3d->rot_angle); // modulate opacity with angle - // ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 + color[3] = 0.f; // more transparent toward the ends + glColor4fv(color); + add_v3_v3v3(end, o, scaled_axis); + glVertex3fv(end); - color[3] = 0.5f; // more opaque toward the center - glColor4fv(color); - glVertex3fv(o); - - color[3] = 0.f; - glColor4fv(color); - sub_v3_v3v3(end, o, scaled_axis); - glVertex3fv(end); + // color[3] = 0.2f + fabsf(rv3d->rot_angle); // modulate opacity with angle + // ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 + + color[3] = 0.5f; // more opaque toward the center + glColor4fv(color); + glVertex3fv(o); + + color[3] = 0.f; + glColor4fv(color); + sub_v3_v3v3(end, o, scaled_axis); + glVertex3fv(end); glEnd(); // -- draw ring around rotation center -- { - #define ROT_AXIS_DETAIL 13 - const float s = 0.05f * scale; - const float step = 2.f * (float)(M_PI / ROT_AXIS_DETAIL); - float angle; - int i; - - float q[4]; // rotate ring so it's perpendicular to axis - const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f; - if (!upright) - { - const float up[3] = {0.f, 0.f, 1.f}; - float vis_angle, vis_axis[3]; - - cross_v3_v3v3(vis_axis, up, rv3d->rot_axis); - vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis)); - axis_angle_to_quat(q, vis_axis, vis_angle); +#define ROT_AXIS_DETAIL 13 + + const float s = 0.05f * scale; + const float step = 2.f * (float)(M_PI / ROT_AXIS_DETAIL); + float angle; + int i; + + float q[4]; // rotate ring so it's perpendicular to axis + const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f; + if (!upright) { + const float up[3] = {0.f, 0.f, 1.f}; + float vis_angle, vis_axis[3]; + + cross_v3_v3v3(vis_axis, up, rv3d->rot_axis); + vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis)); + axis_angle_to_quat(q, vis_axis, vis_angle); } - color[3] = 0.25f; // somewhat faint - glColor4fv(color); - glBegin(GL_LINE_LOOP); - for (i = 0, angle = 0.f; i < ROT_AXIS_DETAIL; ++i, angle += step) - { - float p[3] = { s * cosf(angle), s * sinf(angle), 0.f }; + color[3] = 0.25f; // somewhat faint + glColor4fv(color); + glBegin(GL_LINE_LOOP); + for (i = 0, angle = 0.f; i < ROT_AXIS_DETAIL; ++i, angle += step) { + float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f}; - if (!upright) - mul_qt_v3(q, p); + if (!upright) { + mul_qt_v3(q, p); + } - add_v3_v3(p, o); - glVertex3fv(p); + add_v3_v3(p, o); + glVertex3fv(p); } - glEnd(); + glEnd(); + +#undef ROT_AXIS_DETAIL } color[3] = 1.f; // solid dot @@ -1237,7 +1206,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0); - uiSetRoundBox(15); + uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 19e8d42db2d..761de836cfb 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1017,18 +1017,26 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event if (has_rotation) { - const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; - rv3d->view = RV3D_VIEW_USER; if (U.flag & USER_TRACKBALL) { + const int invert_roll = U.ndof_flag & NDOF_ROLL_INVERT_AXIS; + const int invert_tilt = U.ndof_flag & NDOF_TILT_INVERT_AXIS; + const int invert_rot = U.ndof_flag & NDOF_ROTATE_INVERT_AXIS; + float rot[4]; float axis[3]; float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); - - if (invert) - angle = -angle; - + + if (invert_roll) + axis[2] = -axis[2]; + + if (invert_tilt) + axis[0] = -axis[0]; + + if (invert_rot) + axis[1] = -axis[1]; + // transform rotation axis from view to world coordinates mul_qt_v3(view_inv, axis); @@ -1042,6 +1050,8 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); } else { /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ + const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; + float angle, rot[4]; float xvec[3] = {1,0,0}; @@ -1143,10 +1153,26 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) const float vertical_sensitivity = 0.4f; const float lateral_sensitivity = 0.6f; - float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0], - vertical_sensitivity * ndof->tvec[1], - forward_sensitivity * ndof->tvec[2] - }; + const int invert_panx = U.ndof_flag & NDOF_PANX_INVERT_AXIS; + const int invert_pany = U.ndof_flag & NDOF_PANY_INVERT_AXIS; + const int invert_panz = U.ndof_flag & NDOF_PANZ_INVERT_AXIS; + + float pan_vec[3]; + + if (invert_panx) + pan_vec[0] = -lateral_sensitivity * ndof->tvec[0]; + else + pan_vec[0] = lateral_sensitivity * ndof->tvec[0]; + + if (invert_panz) + pan_vec[1] = -vertical_sensitivity * ndof->tvec[1]; + else + pan_vec[1] = vertical_sensitivity * ndof->tvec[1]; + + if (invert_pany) + pan_vec[2] = -forward_sensitivity * ndof->tvec[2]; + else + pan_vec[2] = forward_sensitivity * ndof->tvec[2]; mul_v3_fl(pan_vec, speed * dt); #endif diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 1796bd4e928..82598e0b5c6 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1091,7 +1091,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float *vec) calculateCenter(t); // Copy center from constraint center. Transform center can be local - VECCOPY(vec, t->con.center); + copy_v3_v3(vec, t->con.center); } @@ -1210,7 +1210,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) mval[0]= x; mval[1]= y; - VECCOPY(vecrot, t->center); + copy_v3_v3(vecrot, t->center); if(t->flag & T_EDIT) { Object *ob= t->obedit; if(ob) mul_m4_v3(ob->obmat, vecrot); @@ -1963,7 +1963,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) * - current space should be local */ unit_m4(cob.matrix); - VECCOPY(cob.matrix[3], td->loc); + copy_v3_v3(cob.matrix[3], td->loc); /* Evaluate valid constraints */ for (con= td->con; con; con= con->next) { @@ -2022,7 +2022,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) } /* copy results from cob->matrix */ - VECCOPY(td->loc, cob.matrix[3]); + copy_v3_v3(td->loc, cob.matrix[3]); } } @@ -2292,8 +2292,8 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) * It needs to be in view space, but we need to take object's offset * into account if in Edit mode. */ - VECCOPY(cursor, curs); - VECCOPY(gcursor, cursor); + copy_v3_v3(cursor, curs); + copy_v3_v3(gcursor, cursor); if (t->flag & T_EDIT) { sub_v3_v3(cursor, t->obedit->obmat[3]); sub_v3_v3(gcursor, t->obedit->obmat[3]); @@ -2336,7 +2336,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2])) continue; /* translate point to center, rotate in such a way that outline==distance */ - VECCOPY(vec, td->iloc); + copy_v3_v3(vec, td->iloc); mul_m3_v3(td->mtx, vec); mul_m4_v3(t->viewmat, vec); sub_v3_v3(vec, t->viewmat[3]); @@ -2603,23 +2603,23 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { /* local constraint shouldn't alter center */ if (t->around == V3D_LOCAL) { if (t->flag & T_OBJECT) { - VECCOPY(center, td->center); + copy_v3_v3(center, td->center); } else if (t->flag & T_EDIT) { if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { - VECCOPY(center, td->center); + copy_v3_v3(center, td->center); } else { - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); } } else { - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); } } else { - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); } if (td->ext) { @@ -2719,10 +2719,10 @@ int Resize(TransInfo *t, const int mval[2]) if (t->flag & T_AUTOVALUES) { - VECCOPY(size, t->auto_values); + copy_v3_v3(size, t->auto_values); } - VECCOPY(t->values, size); + copy_v3_v3(t->values, size); size_to_mat3( mat,size); @@ -3020,7 +3020,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short mul_m3_m3m3(smat, td->smtx, totmat); /* calculate the total rotatation in eulers */ - VECCOPY(eul, td->ext->irot); + copy_v3_v3(eul, td->ext->irot); eulO_to_mat3( eulmat,eul, td->ext->rotOrder); /* mat = transform, obmat = bone rotation */ @@ -3030,7 +3030,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* and apply (to end result only) */ protectedRotateBits(td->protectflag, eul, td->ext->irot); - VECCOPY(td->ext->rot, eul); + copy_v3_v3(td->ext->rot, eul); } constraintRotLim(t, td); @@ -3100,7 +3100,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* and apply */ protectedRotateBits(td->protectflag, eul, td->ext->irot); - VECCOPY(td->ext->rot, eul); + copy_v3_v3(td->ext->rot, eul); } constraintRotLim(t, td); @@ -3244,8 +3244,8 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2])) float mat[3][3], totmat[3][3], smat[3][3]; float phi[2]; - VECCOPY(axis1, t->persinv[0]); - VECCOPY(axis2, t->persinv[1]); + copy_v3_v3(axis1, t->persinv[0]); + copy_v3_v3(axis2, t->persinv[1]); normalize_v3(axis1); normalize_v3(axis2); @@ -3341,7 +3341,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { else { float dvec[3]; - VECCOPY(dvec, vec); + copy_v3_v3(dvec, vec); applyAspectRatio(t, dvec); dist = len_v3(vec); @@ -3448,7 +3448,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) { t->con.applyVec(t, td, vec, tvec, pvec); } else { - VECCOPY(tvec, vec); + copy_v3_v3(tvec, vec); } mul_m3_v3(td->smtx, tvec); @@ -3475,7 +3475,7 @@ int Translation(TransInfo *t, const int UNUSED(mval[2])) } applySnapping(t, t->values); t->con.applyVec(t, NULL, t->values, tvec, pvec); - VECCOPY(t->values, tvec); + copy_v3_v3(t->values, tvec); headerTranslation(t, pvec, str); } else { @@ -3564,7 +3564,7 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) if (td->flag & TD_SKIP) continue; - VECCOPY(vec, td->axismtx[2]); + copy_v3_v3(vec, td->axismtx[2]); mul_v3_fl(vec, distance); mul_v3_fl(vec, td->factor); @@ -4608,7 +4608,7 @@ static int createSlideVerts(TransInfo *t) add_v3_v3(start, end); mul_v3_fl(start, 0.5f*(1.0f/totvec)); - VECCOPY(vec, start); + copy_v3_v3(vec, start); start[0] = t->mval[0]; start[1] = t->mval[1]; add_v3_v3v3(end, start, vec); @@ -5215,7 +5215,7 @@ int Align(TransInfo *t, const int UNUSED(mval[2])) int i; /* saving original center */ - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); for(i = 0 ; i < t->total; i++, td++) { @@ -5229,11 +5229,11 @@ int Align(TransInfo *t, const int UNUSED(mval[2])) /* around local centers */ if (t->flag & (T_OBJECT|T_POSE)) { - VECCOPY(t->center, td->center); + copy_v3_v3(t->center, td->center); } else { if(t->settings->selectmode & SCE_SELECT_FACE) { - VECCOPY(t->center, td->center); + copy_v3_v3(t->center, td->center); } } @@ -5245,7 +5245,7 @@ int Align(TransInfo *t, const int UNUSED(mval[2])) } /* restoring original center */ - VECCOPY(t->center, center); + copy_v3_v3(t->center, center); recalcData(t); @@ -5317,7 +5317,7 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2])) float pvec[3] = {0.0f, 0.0f, 0.0f}; float tvec[3]; t->con.applyVec(t, NULL, t->values, tvec, pvec); - VECCOPY(t->values, tvec); + copy_v3_v3(t->values, tvec); } else { snapGrid(t, t->values); @@ -5423,9 +5423,13 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, { /* snap key to nearest frame? */ if (autosnap == SACTSNAP_FRAME) { + +#if 0 /* 'doTime' disabled for now */ + const Scene *scene= t->scene; const short doTime= 0; //getAnimEdit_DrawTime(t); // NOTE: this works, but may be confusing behaviour given the option's label, hence disabled const double secf= FPS; +#endif double val; /* convert frame to nla-action time (if needed) */ @@ -5434,11 +5438,17 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, else val= *(td->val); +#if 0 /* 'doTime' disabled for now */ + /* do the snapping to nearest frame/second */ - if (doTime) + if (doTime) { val= (float)( floor((val/secf) + 0.5f) * secf ); + } else +#endif + { val= (float)( floor(val+0.5f) ); + } /* convert frame out of nla-action time */ if (adt) diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index be5f539431f..a06de9fa1ce 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -239,7 +239,7 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3 if(factor<0.0f) factor*= -factor; else factor*= factor; - VECCOPY(out, axis); + copy_v3_v3(out, axis); normalize_v3(out); mul_v3_fl(out, -factor); /* -factor makes move down going backwards */ } @@ -261,7 +261,7 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3 /* give arbitrary large value if projection is impossible */ factor = dot_v3v3(axis, norm); if (1.0f - fabsf(factor) < 0.0002f) { - VECCOPY(out, axis); + copy_v3_v3(out, axis); if (factor > 0) { mul_v3_fl(out, 1000000000.0f); } else { @@ -300,7 +300,7 @@ static void planeProjection(TransInfo *t, float in[3], float out[3]) { } factor = dot_v3v3(vec, vec) / factor; - VECCOPY(vec, norm); + copy_v3_v3(vec, norm); mul_v3_fl(vec, factor); add_v3_v3v3(out, in, vec); @@ -317,7 +317,7 @@ static void planeProjection(TransInfo *t, float in[3], float out[3]) { static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3], float pvec[3]) { - VECCOPY(out, in); + copy_v3_v3(out, in); if (!td && t->con.mode & CON_APPLY) { mul_m3_v3(t->con.pmtx, out); @@ -332,13 +332,13 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo float c[3]; if (t->con.mode & CON_AXIS0) { - VECCOPY(c, t->con.mtx[0]); + copy_v3_v3(c, t->con.mtx[0]); } else if (t->con.mode & CON_AXIS1) { - VECCOPY(c, t->con.mtx[1]); + copy_v3_v3(c, t->con.mtx[1]); } else if (t->con.mode & CON_AXIS2) { - VECCOPY(c, t->con.mtx[2]); + copy_v3_v3(c, t->con.mtx[2]); } axisProjection(t, c, in, out); } @@ -360,7 +360,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo static void applyObjectConstraintVec(TransInfo *t, TransData *td, float in[3], float out[3], float pvec[3]) { - VECCOPY(out, in); + copy_v3_v3(out, in); if (t->con.mode & CON_APPLY) { if (!td) { mul_m3_v3(t->con.pmtx, out); @@ -373,18 +373,18 @@ static void applyObjectConstraintVec(TransInfo *t, TransData *td, float in[3], f float c[3]; if (t->con.mode & CON_AXIS0) { - VECCOPY(c, t->con.mtx[0]); + copy_v3_v3(c, t->con.mtx[0]); } else if (t->con.mode & CON_AXIS1) { - VECCOPY(c, t->con.mtx[1]); + copy_v3_v3(c, t->con.mtx[1]); } else if (t->con.mode & CON_AXIS2) { - VECCOPY(c, t->con.mtx[2]); + copy_v3_v3(c, t->con.mtx[2]); } axisProjection(t, c, in, out); } postConstraintChecks(t, out, pvec); - VECCOPY(out, pvec); + copy_v3_v3(out, pvec); } else { int i=0; @@ -481,15 +481,15 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3], fl switch(mode) { case CON_AXIS0: case (CON_AXIS1|CON_AXIS2): - VECCOPY(vec, t->con.mtx[0]); + copy_v3_v3(vec, t->con.mtx[0]); break; case CON_AXIS1: case (CON_AXIS0|CON_AXIS2): - VECCOPY(vec, t->con.mtx[1]); + copy_v3_v3(vec, t->con.mtx[1]); break; case CON_AXIS2: case (CON_AXIS0|CON_AXIS1): - VECCOPY(vec, t->con.mtx[2]); + copy_v3_v3(vec, t->con.mtx[2]); break; } /* don't flip axis if asked to or if num input */ @@ -528,15 +528,15 @@ static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3], switch(mode) { case CON_AXIS0: case (CON_AXIS1|CON_AXIS2): - VECCOPY(vec, td->axismtx[0]); + copy_v3_v3(vec, td->axismtx[0]); break; case CON_AXIS1: case (CON_AXIS0|CON_AXIS2): - VECCOPY(vec, td->axismtx[1]); + copy_v3_v3(vec, td->axismtx[1]); break; case CON_AXIS2: case (CON_AXIS0|CON_AXIS1): - VECCOPY(vec, td->axismtx[2]); + copy_v3_v3(vec, td->axismtx[2]); break; } if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) { @@ -724,7 +724,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) glPushMatrix(); - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); if((t->spacetype == SPACE_VIEW3D) && t->obedit) { @@ -897,7 +897,7 @@ static void setNearestAxis3d(TransInfo *t) zfac = len_v3(t->persinv[0]) * 2.0f/t->ar->winx * zfac * 30.0f; for (i = 0; i<3; i++) { - VECCOPY(axis, t->con.mtx[i]); + copy_v3_v3(axis, t->con.mtx[i]); mul_v3_fl(axis, zfac); /* now we can project to get window coordinate */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index cae64899aeb..b98cd277f80 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -269,7 +269,7 @@ static void createTransTexspace(TransInfo *t) td->ext= t->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); td->flag= TD_SELECTED; - VECCOPY(td->center, ob->obmat[3]); + copy_v3_v3(td->center, ob->obmat[3]); td->ob = ob; copy_m3_m4(td->mtx, ob->obmat); @@ -282,9 +282,9 @@ static void createTransTexspace(TransInfo *t) *texflag &= ~AUTOSPACE; } - VECCOPY(td->iloc, td->loc); - VECCOPY(td->ext->irot, td->ext->rot); - VECCOPY(td->ext->isize, td->ext->size); + copy_v3_v3(td->iloc, td->loc); + copy_v3_v3(td->ext->irot, td->ext->rot); + copy_v3_v3(td->ext->isize, td->ext->size); } /* ********************* edge (for crease) ***** */ @@ -420,7 +420,7 @@ static short apply_targetless_ik(Object *ob) copy_m4_m3(offs_bone, bone->bone_mat); /* The bone's root offset (is in the parent's coordinate system) */ - VECCOPY(offs_bone[3], bone->head); + copy_v3_v3(offs_bone[3], bone->head); /* Get the length translation of parent (length along y axis) */ offs_bone[3][1]+= parbone->length; @@ -431,7 +431,7 @@ static short apply_targetless_ik(Object *ob) copy_m4_m4(rmat, parbone->arm_mat); /* rmat used as temp */ /* the location of actual parent transform */ - VECCOPY(rmat[3], offs_bone[3]); + copy_v3_v3(rmat[3], offs_bone[3]); offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f; mul_m4_v3(parchan->parent->pose_mat, rmat[3]); @@ -449,7 +449,7 @@ static short apply_targetless_ik(Object *ob) else { copy_m4_m3(tmat, bone->bone_mat); - VECCOPY(tmat[3], bone->head); + copy_v3_v3(tmat[3], bone->head); invert_m4_m4(imat, tmat); } /* result matrix */ @@ -491,7 +491,7 @@ static short apply_targetless_ik(Object *ob) /* causes problems with some constraints (e.g. childof), so disable this */ /* as it is IK shouldn't affect location directly */ - /* VECCOPY(parchan->loc, rmat[3]); */ + /* copy_v3_v3(parchan->loc, rmat[3]); */ } } @@ -511,8 +511,8 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr float cmat[3][3], tmat[3][3]; float vec[3]; - VECCOPY(vec, pchan->pose_mat[3]); - VECCOPY(td->center, vec); + copy_v3_v3(vec, pchan->pose_mat[3]); + copy_v3_v3(td->center, vec); td->ob = ob; td->flag = TD_SELECTED; @@ -530,10 +530,10 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->protectflag= pchan->protectflag; td->loc = pchan->loc; - VECCOPY(td->iloc, pchan->loc); + copy_v3_v3(td->iloc, pchan->loc); td->ext->size= pchan->size; - VECCOPY(td->ext->isize, pchan->size); + copy_v3_v3(td->ext->isize, pchan->size); if (pchan->rotmode > 0) { td->ext->rot= pchan->eul; @@ -541,7 +541,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->rotAngle= NULL; td->ext->quat= NULL; - VECCOPY(td->ext->irot, pchan->eul); + copy_v3_v3(td->ext->irot, pchan->eul); } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { td->ext->rot= NULL; @@ -550,7 +550,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->quat= NULL; td->ext->irotAngle= pchan->rotAngle; - VECCOPY(td->ext->irotAxis, pchan->rotAxis); + copy_v3_v3(td->ext->irotAxis, pchan->rotAxis); } else { td->ext->rot= NULL; @@ -626,7 +626,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr else { // abusive storage of scale in the loc pointer :) td->loc= &bone->xwidth; - VECCOPY (td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); td->val= NULL; } } @@ -636,13 +636,13 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr bKinematicConstraint *data= has_targetless_ik(pchan); if(data) { if(data->flag & CONSTRAINT_IK_TIP) { - VECCOPY(data->grabtarget, pchan->pose_tail); + copy_v3_v3(data->grabtarget, pchan->pose_tail); } else { - VECCOPY(data->grabtarget, pchan->pose_head); + copy_v3_v3(data->grabtarget, pchan->pose_head); } td->loc = data->grabtarget; - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); data->flag |= CONSTRAINT_IK_AUTO; /* only object matrix correction */ @@ -885,7 +885,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) else data->flag= CONSTRAINT_IK_TIP; data->flag |= CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO; - VECCOPY(data->grabtarget, pchan->pose_tail); + copy_v3_v3(data->grabtarget, pchan->pose_tail); data->rootbone= 0; /* watch-it! has to be 0 here, since we're still on the same bone for the first time through the loop [#25885] */ /* we only include bones that are part of a continual connected chain */ @@ -1109,7 +1109,7 @@ static void createTransArmatureVerts(TransInfo *t) td->val= &ebo->rad_head; td->ival= *td->val; - VECCOPY (td->center, ebo->head); + copy_v3_v3(td->center, ebo->head); td->flag= TD_SELECTED; copy_m3_m3(td->smtx, smtx); @@ -1125,7 +1125,7 @@ static void createTransArmatureVerts(TransInfo *t) { td->val= &ebo->rad_tail; td->ival= *td->val; - VECCOPY (td->center, ebo->tail); + copy_v3_v3(td->center, ebo->tail); td->flag= TD_SELECTED; copy_m3_m3(td->smtx, smtx); @@ -1152,10 +1152,10 @@ static void createTransArmatureVerts(TransInfo *t) { // abusive storage of scale in the loc pointer :) td->loc= &ebo->xwidth; - VECCOPY (td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); td->val= NULL; } - VECCOPY (td->center, ebo->head); + copy_v3_v3(td->center, ebo->head); td->flag= TD_SELECTED; /* use local bone matrix */ @@ -1181,7 +1181,7 @@ static void createTransArmatureVerts(TransInfo *t) td->val= &(ebo->roll); td->ival= ebo->roll; - VECCOPY (td->center, ebo->head); + copy_v3_v3(td->center, ebo->head); td->flag= TD_SELECTED; td->ext = NULL; @@ -1194,8 +1194,8 @@ static void createTransArmatureVerts(TransInfo *t) { if (ebo->flag & BONE_TIPSEL) { - VECCOPY (td->iloc, ebo->tail); - VECCOPY (td->center, td->iloc); + copy_v3_v3(td->iloc, ebo->tail); + copy_v3_v3(td->center, td->iloc); td->loc= ebo->tail; td->flag= TD_SELECTED; if (ebo->flag & BONE_EDITMODE_LOCKED) @@ -1220,8 +1220,8 @@ static void createTransArmatureVerts(TransInfo *t) } if (ebo->flag & BONE_ROOTSEL) { - VECCOPY (td->iloc, ebo->head); - VECCOPY (td->center, td->iloc); + copy_v3_v3(td->iloc, ebo->head); + copy_v3_v3(td->center, td->iloc); td->loc= ebo->head; td->flag= TD_SELECTED; if (ebo->flag & BONE_EDITMODE_LOCKED) @@ -1279,8 +1279,8 @@ static void createTransMBallVerts(TransInfo *t) for(ml= mb->editelems->first; ml; ml= ml->next) { if(propmode || (ml->flag & SELECT)) { td->loc= &ml->x; - VECCOPY(td->iloc, td->loc); - VECCOPY(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + copy_v3_v3(td->center, td->loc); if(ml->flag & SELECT) td->flag= TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE; else td->flag= TD_USEQUAT; @@ -1444,9 +1444,9 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) ((bezt->f2 & SELECT) && hide_handles) || ((bezt->f1 & SELECT) && hide_handles == 0) ) { - VECCOPY(td->iloc, bezt->vec[0]); + copy_v3_v3(td->iloc, bezt->vec[0]); td->loc= bezt->vec[0]; - VECCOPY(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1:0]); + copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1:0]); if (hide_handles) { if(bezt->f2 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; @@ -1469,9 +1469,9 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) /* This is the Curve Point, the other two are handles */ if(propmode || (bezt->f2 & SELECT)) { - VECCOPY(td->iloc, bezt->vec[1]); + copy_v3_v3(td->iloc, bezt->vec[1]); td->loc= bezt->vec[1]; - VECCOPY(td->center, td->loc); + copy_v3_v3(td->center, td->loc); if(bezt->f2 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; td->ext = NULL; @@ -1503,9 +1503,9 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) ((bezt->f2 & SELECT) && hide_handles) || ((bezt->f3 & SELECT) && hide_handles == 0) ) { - VECCOPY(td->iloc, bezt->vec[2]); + copy_v3_v3(td->iloc, bezt->vec[2]); td->loc= bezt->vec[2]; - VECCOPY(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1:2]); + copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1:2]); if (hide_handles) { if(bezt->f2 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; @@ -1547,9 +1547,9 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) { if(bp->hide==0) { if(propmode || (bp->f1 & SELECT)) { - VECCOPY(td->iloc, bp->vec); + copy_v3_v3(td->iloc, bp->vec); td->loc= bp->vec; - VECCOPY(td->center, td->loc); + copy_v3_v3(td->center, td->loc); if(bp->f1 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; td->ext = NULL; @@ -1619,9 +1619,9 @@ static void createTransLatticeVerts(TransInfo *t) while(a--) { if(propmode || (bp->f1 & SELECT)) { if(bp->hide==0) { - VECCOPY(td->iloc, bp->vec); + copy_v3_v3(td->iloc, bp->vec); td->loc= bp->vec; - VECCOPY(td->center, td->loc); + copy_v3_v3(td->center, td->loc); if(bp->f1 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; copy_m3_m3(td->smtx, smtx); @@ -1714,15 +1714,15 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) for(k=0, key=point->keys; k<point->totkey; k++, key++) { if(key->flag & PEK_USE_WCO) { - VECCOPY(key->world_co, key->co); + copy_v3_v3(key->world_co, key->co); mul_m4_v3(mat, key->world_co); td->loc = key->world_co; } else td->loc = key->co; - VECCOPY(td->iloc, td->loc); - VECCOPY(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + copy_v3_v3(td->center, td->loc); if(key->flag & PEK_SELECT) td->flag |= TD_SELECTED; @@ -1787,13 +1787,13 @@ void flushTransParticles(TransInfo *t) invert_m4_m4(imat,mat); for(k=0, key=point->keys; k<point->totkey; k++, key++) { - VECCOPY(co, key->world_co); + copy_v3_v3(co, key->world_co); mul_m4_v3(imat, co); /* optimization for proportional edit */ if(!propmode || !compare_v3v3(key->co, co, 0.0001f)) { - VECCOPY(key->co, co); + copy_v3_v3(key->co, co); point->flag |= PEP_EDIT_RECALC; } } @@ -1910,7 +1910,7 @@ static void get_face_center(float *cent, EditMesh *em, EditVert *eve) if(efa->v1==eve || efa->v2==eve || efa->v3==eve || efa->v4==eve) break; if(efa) { - VECCOPY(cent, efa->cent); + copy_v3_v3(cent, efa->cent); } } @@ -1924,13 +1924,13 @@ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert //else td->loc = eve->co; - VECCOPY(td->center, td->loc); + copy_v3_v3(td->center, td->loc); if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE)) get_face_center(td->center, em, eve); - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); // Setting normals - VECCOPY(td->axismtx[2], eve->no); + copy_v3_v3(td->axismtx[2], eve->no); td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = @@ -1960,9 +1960,9 @@ static void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head if ( (vtd = BME_get_transdata(td,v)) ) { tob->loc = vtd->loc; tob->val = &vtd->factor; - VECCOPY(tob->iloc,vtd->co); - VECCOPY(tob->center,vtd->org); - VECCOPY(tob->axismtx[0],vtd->vec); + copy_v3_v3(tob->iloc,vtd->co); + copy_v3_v3(tob->center,vtd->org); + copy_v3_v3(tob->axismtx[0],vtd->vec); tob->axismtx[1][0] = vtd->max ? *vtd->max : 0; tob++; i++; @@ -2305,8 +2305,8 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f td->flag = 0; td->loc = td2d->loc; - VECCOPY(td->center, td->loc); - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -2606,10 +2606,10 @@ static void createTransNlaData(bContext *C, TransInfo *t) /* now, link the transform data up to this data */ if (ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_EXTEND)) { td->loc= tdn->h1; - VECCOPY(td->iloc, tdn->h1); + copy_v3_v3(td->iloc, tdn->h1); /* store all the other gunk that is required by transform */ - VECCOPY(td->center, center); + copy_v3_v3(td->center, center); memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -2638,10 +2638,10 @@ static void createTransNlaData(bContext *C, TransInfo *t) /* now, link the transform data up to this data */ if (ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_EXTEND)) { td->loc= tdn->h2; - VECCOPY(td->iloc, tdn->h2); + copy_v3_v3(td->iloc, tdn->h2); /* store all the other gunk that is required by transform */ - VECCOPY(td->center, center); + copy_v3_v3(td->center, center); memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -3194,7 +3194,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, td->center[1] = cent[1]; td->center[2] = 0.0f; - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); } else { td2d->loc[0] = loc[0]; @@ -3203,8 +3203,8 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, td2d->loc2d = loc; td->loc = td2d->loc; - VECCOPY(td->center, cent); - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->center, cent); + copy_v3_v3(td->iloc, td->loc); } if (td->flag & TD_MOVEHANDLE1) { @@ -3903,8 +3903,8 @@ static TransData *SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq td->flag = 0; td->loc = td2d->loc; - VECCOPY(td->center, td->loc); - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -4255,7 +4255,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) td->ob = ob; td->loc = ob->loc; - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); if (ob->rotmode > 0) { td->ext->rot= ob->rot; @@ -4263,8 +4263,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) td->ext->rotAngle= NULL; td->ext->quat= NULL; - VECCOPY(td->ext->irot, ob->rot); - VECCOPY(td->ext->drot, ob->drot); + copy_v3_v3(td->ext->irot, ob->rot); + copy_v3_v3(td->ext->drot, ob->drot); } else if (ob->rotmode == ROT_MODE_AXISANGLE) { td->ext->rot= NULL; @@ -4273,9 +4273,9 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) td->ext->quat= NULL; td->ext->irotAngle= ob->rotAngle; - VECCOPY(td->ext->irotAxis, ob->rotAxis); + copy_v3_v3(td->ext->irotAxis, ob->rotAxis); // td->ext->drotAngle= ob->drotAngle; // XXX, not implimented - // VECCOPY(td->ext->drotAxis, ob->drotAxis); // XXX, not implimented + // copy_v3_v3(td->ext->drotAxis, ob->drotAxis); // XXX, not implimented } else { td->ext->rot= NULL; @@ -4289,10 +4289,10 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) td->ext->rotOrder=ob->rotmode; td->ext->size = ob->size; - VECCOPY(td->ext->isize, ob->size); - VECCOPY(td->ext->dsize, ob->dsize); + copy_v3_v3(td->ext->isize, ob->size); + copy_v3_v3(td->ext->dsize, ob->dsize); - VECCOPY(td->center, ob->obmat[3]); + copy_v3_v3(td->center, ob->obmat[3]); copy_m4_m4(td->ext->obmat, ob->obmat); @@ -5202,8 +5202,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) } td->loc = td2d->loc; - VECCOPY(td->center, td->loc); - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index ec76bb3ac35..76c81662ce8 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -115,9 +115,9 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3]) { float p1[4], p2[4]; - VECCOPY(p1, coord); + copy_v3_v3(p1, coord); p1[3] = 1.0f; - VECCOPY(p2, p1); + copy_v3_v3(p2, p1); p2[3] = 1.0f; mul_m4_v4(t->viewmat, p2); @@ -130,7 +130,7 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3]) sub_v3_v3v3(vec, p1, p2); } else { - VECCOPY(vec, t->viewinv[2]); + copy_v3_v3(vec, t->viewinv[2]); } normalize_v3(vec); } @@ -144,7 +144,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) int axis = 0; for (; md; md=md->next) { - if (md->type==eModifierType_Mirror) { + if ((md->type==eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { MirrorModifierData *mmd = (MirrorModifierData*) md; if(mmd->flag & MOD_MIR_CLIPPING) { @@ -694,12 +694,12 @@ static void recalcData_view3d(TransInfo *t) if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ /* If this bone has a parent tip that has been moved */ if (ebo->parent->flag & BONE_TIPSEL){ - VECCOPY (ebo->head, ebo->parent->tail); + copy_v3_v3 (ebo->head, ebo->parent->tail); if(t->mode==TFM_BONE_ENVELOPE) ebo->rad_head= ebo->parent->rad_tail; } /* If this bone has a parent tip that has NOT been moved */ else{ - VECCOPY (ebo->parent->tail, ebo->head); + copy_v3_v3 (ebo->parent->tail, ebo->head); if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; } } @@ -736,7 +736,7 @@ static void recalcData_view3d(TransInfo *t) float qrot[4]; ebo = td->extra; - VECCOPY(up_axis, td->axismtx[2]); + copy_v3_v3(up_axis, td->axismtx[2]); if (t->mode != TFM_ROTATION) { @@ -1259,12 +1259,12 @@ void applyTransObjects(TransInfo *t) TransData *td; for (td = t->data; td < t->data + t->total; td++) { - VECCOPY(td->iloc, td->loc); + copy_v3_v3(td->iloc, td->loc); if (td->ext->rot) { - VECCOPY(td->ext->irot, td->ext->rot); + copy_v3_v3(td->ext->irot, td->ext->rot); } if (td->ext->size) { - VECCOPY(td->ext->isize, td->ext->size); + copy_v3_v3(td->ext->isize, td->ext->size); } } recalcData(t); @@ -1273,7 +1273,7 @@ void applyTransObjects(TransInfo *t) static void restoreElement(TransData *td) { /* TransData for crease has no loc */ if (td->loc) { - VECCOPY(td->loc, td->iloc); + copy_v3_v3(td->loc, td->iloc); } if (td->val) { *td->val = td->ival; @@ -1281,17 +1281,17 @@ static void restoreElement(TransData *td) { if (td->ext && (td->flag&TD_NO_EXT)==0) { if (td->ext->rot) { - VECCOPY(td->ext->rot, td->ext->irot); + copy_v3_v3(td->ext->rot, td->ext->irot); } if(td->ext->rotAngle) { *td->ext->rotAngle= td->ext->irotAngle; } if(td->ext->rotAxis) { - VECCOPY(td->ext->rotAxis, td->ext->irotAxis); + copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis); } /* XXX, drotAngle & drotAxis not used yet */ if (td->ext->size) { - VECCOPY(td->ext->size, td->ext->isize); + copy_v3_v3(td->ext->size, td->ext->isize); } if (td->ext->quat) { QUATCOPY(td->ext->quat, td->ext->iquat); @@ -1335,7 +1335,7 @@ void calculateCenter2D(TransInfo *t) Object *ob= t->obedit?t->obedit:t->poseobj; float vec[3]; - VECCOPY(vec, t->center); + copy_v3_v3(vec, t->center); mul_m4_v3(ob->obmat, vec); projectIntView(t, vec, t->center2d); } @@ -1349,7 +1349,7 @@ void calculateCenterCursor(TransInfo *t) float *cursor; cursor = give_cursor(t->scene, t->view); - VECCOPY(t->center, cursor); + copy_v3_v3(t->center, cursor); /* If edit or pose mode, move cursor in local space */ if (t->flag & (T_EDIT|T_POSE)) { @@ -1421,7 +1421,7 @@ void calculateCenterMedian(TransInfo *t) } if(i) mul_v3_fl(partial, 1.0f / total); - VECCOPY(t->center, partial); + copy_v3_v3(t->center, partial); calculateCenter2D(t); } @@ -1446,8 +1446,8 @@ void calculateCenterBound(TransInfo *t) } } else { - VECCOPY(max, t->data[i].center); - VECCOPY(min, t->data[i].center); + copy_v3_v3(max, t->data[i].center); + copy_v3_v3(min, t->data[i].center); } } add_v3_v3v3(t->center, min, max); @@ -1501,7 +1501,7 @@ void calculateCenter(TransInfo *t) Object *ob= OBACT; if(ob) { - VECCOPY(t->center, ob->obmat[3]); + copy_v3_v3(t->center, ob->obmat[3]); projectIntView(t, t->center, t->center2d); } } @@ -1510,7 +1510,7 @@ void calculateCenter(TransInfo *t) } /* setting constraint center */ - VECCOPY(t->con.center, t->center); + copy_v3_v3(t->con.center, t->center); if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; @@ -1530,7 +1530,7 @@ void calculateCenter(TransInfo *t) { float axis[3]; /* persinv is nasty, use viewinv instead, always right */ - VECCOPY(axis, t->viewinv[2]); + copy_v3_v3(axis, t->viewinv[2]); normalize_v3(axis); /* 6.0 = 6 grid units */ @@ -1543,8 +1543,8 @@ void calculateCenter(TransInfo *t) /* rotate only needs correct 2d center, grab needs initgrabz() value */ if(t->mode==TFM_TRANSLATION) { - VECCOPY(t->center, axis); - VECCOPY(t->con.center, t->center); + copy_v3_v3(t->center, axis); + copy_v3_v3(t->con.center, t->center); } } } @@ -1557,7 +1557,7 @@ void calculateCenter(TransInfo *t) Object *ob= t->obedit?t->obedit:t->poseobj; float vec[3]; - VECCOPY(vec, t->center); + copy_v3_v3(vec, t->center); mul_m4_v3(ob->obmat, vec); initgrabz(t->ar->regiondata, vec[0], vec[1], vec[2]); } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index d62227a122d..491666c4ac9 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -884,7 +884,7 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, if(arcs) { /* clipplane makes nice handles, calc here because of multmatrix but with translate! */ - VECCOPY(plane, rv3d->viewinv[2]); + VECCOPY(plane, rv3d->viewinv[2]); /* float -> double */ plane[3]= -0.02f*size; // clip just a bit more glClipPlane(GL_CLIP_PLANE0, plane); } @@ -1498,15 +1498,15 @@ void BIF_draw_manipulator(const bContext *C) if(v3d->around==V3D_ACTIVE && scene->obedit==NULL) { Object *ob= OBACT; if(ob && !(ob->mode & OB_MODE_POSE)) - VECCOPY(rv3d->twmat[3], ob->obmat[3]); + copy_v3_v3(rv3d->twmat[3], ob->obmat[3]); } break; case V3D_LOCAL: case V3D_CENTROID: - VECCOPY(rv3d->twmat[3], scene->twcent); + copy_v3_v3(rv3d->twmat[3], scene->twcent); break; case V3D_CURSOR: - VECCOPY(rv3d->twmat[3], give_cursor(scene, v3d)); + copy_v3_v3(rv3d->twmat[3], give_cursor(scene, v3d)); break; } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 2d539055db3..847fd951bcc 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -222,7 +222,7 @@ int createSpaceNormal(float mat[3][3], float normal[3]) { float tangent[3] = {0.0f, 0.0f, 1.0f}; - VECCOPY(mat[2], normal); + copy_v3_v3(mat[2], normal); if (normalize_v3(mat[2]) == 0.0f) { return 0; /* error return */ } @@ -243,7 +243,7 @@ int createSpaceNormal(float mat[3][3], float normal[3]) int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) { - VECCOPY(mat[2], normal); + copy_v3_v3(mat[2], normal); if (normalize_v3(mat[2]) == 0.0f) { return 0; /* error return */ } @@ -659,7 +659,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], for(eed= em->edges.first; eed; eed= eed->next) { if(eed->f & SELECT) { /* use average vert normals as plane and edge vector as normal */ - VECCOPY(plane, eed->v1->no); + copy_v3_v3(plane, eed->v1->no); VECADD(plane, plane, eed->v2->no); sub_v3_v3v3(normal, eed->v2->co, eed->v1->co); break; @@ -680,7 +680,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else { v2 = eve; - VECCOPY(plane, v1->no); + copy_v3_v3(plane, v1->no); VECADD(plane, plane, v2->no); sub_v3_v3v3(normal, v2->co, v1->co); break; @@ -694,7 +694,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], for (eve = em->verts.first; eve; eve = eve->next) { if ( eve->f & SELECT ) { - VECCOPY(normal, eve->no); + copy_v3_v3(normal, eve->no); break; } } @@ -792,7 +792,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], /* Rotation of MetaElem is stored in quat */ quat_to_mat4( mat,ml_sel->quat); - VECCOPY(normal, mat[2]); + copy_v3_v3(normal, mat[2]); negate_v3_v3(plane, mat[1]); @@ -893,8 +893,8 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } if (ob) { - VECCOPY(normal, ob->obmat[2]); - VECCOPY(plane, ob->obmat[1]); + copy_v3_v3(normal, ob->obmat[2]); + copy_v3_v3(plane, ob->obmat[1]); } result = ORIENTATION_NORMAL; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index ca89670dedb..17fd7517d71 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -264,7 +264,7 @@ void applyProject(TransInfo *t) if (td->flag & TD_SKIP) continue; - VECCOPY(iloc, td->loc); + copy_v3_v3(iloc, td->loc); if (t->flag & (T_EDIT|T_POSE)) { Object *ob = t->obedit?t->obedit:t->poseobj; @@ -274,7 +274,7 @@ void applyProject(TransInfo *t) { td->ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; object_handle_update(t->scene, td->ob); - VECCOPY(iloc, td->ob->obmat[3]); + copy_v3_v3(iloc, td->ob->obmat[3]); } project_float(t->ar, iloc, mval); @@ -543,7 +543,7 @@ void addSnapPoint(TransInfo *t) if (t->tsnap.status & POINT_INIT) { TransSnapPoint *p = MEM_callocN(sizeof(TransSnapPoint), "SnapPoint"); - VECCOPY(p->co, t->tsnap.snapPoint); + copy_v3_v3(p->co, t->tsnap.snapPoint); BLI_addtail(&t->tsnap.points, p); @@ -580,7 +580,7 @@ void getSnapPoint(TransInfo *t, float vec[3]) mul_v3_fl(vec, 1.0f / total); } else { - VECCOPY(vec, t->tsnap.snapPoint) + copy_v3_v3(vec, t->tsnap.snapPoint); } } @@ -628,7 +628,7 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3]) { float angle, start[3], end[3], center[3]; - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; mul_m4_v3(ob->obmat, center); @@ -684,7 +684,7 @@ float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) { float d1[3], d2[3], center[3]; - VECCOPY(center, t->center); + copy_v3_v3(center, t->center); if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; mul_m4_v3(ob->obmat, center); @@ -784,12 +784,12 @@ void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) } else { - VECCOPY(vec, p1->p); + copy_v3_v3(vec, p1->p); } if (last_p == NULL) { - VECCOPY(p, vec); + copy_v3_v3(p, vec); max_dist = 0; break; } @@ -798,7 +798,7 @@ void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) if (new_dist < max_dist) { - VECCOPY(p, vec); + copy_v3_v3(p, vec); max_dist = new_dist; } } @@ -806,7 +806,7 @@ void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) if (max_dist != FLT_MAX) { - VECCOPY(loc, p); + copy_v3_v3(loc, p); /* XXX, is there a correct normal in this case ???, for now just z up */ no[0]= 0.0; no[1]= 0.0; @@ -830,11 +830,11 @@ void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) if (dot_v3v3(tangent, tangent) > 0) { - VECCOPY(t->tsnap.snapTangent, tangent); + copy_v3_v3(t->tsnap.snapTangent, tangent); } - VECCOPY(t->tsnap.snapPoint, loc); - VECCOPY(t->tsnap.snapNormal, no); + copy_v3_v3(t->tsnap.snapPoint, loc); + copy_v3_v3(t->tsnap.snapNormal, no); t->tsnap.status |= POINT_INIT; } @@ -873,7 +873,7 @@ void TargetSnapCenter(TransInfo *t) // Only need to calculate once if ((t->tsnap.status & TARGET_INIT) == 0) { - VECCOPY(t->tsnap.snapTarget, t->center); + copy_v3_v3(t->tsnap.snapTarget, t->center); if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; mul_m4_v3(ob->obmat, t->tsnap.snapTarget); @@ -903,7 +903,7 @@ void TargetSnapActive(TransInfo *t) if (active_td) { - VECCOPY(t->tsnap.snapTarget, active_td->center); + copy_v3_v3(t->tsnap.snapTarget, active_td->center); if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; @@ -974,14 +974,14 @@ void TargetSnapClosest(TransInfo *t) float loc[3]; float dist; - VECCOPY(loc, bb->vec[j]); + copy_v3_v3(loc, bb->vec[j]); mul_m4_v3(td->ext->obmat, loc); dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint); if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist)) { - VECCOPY(t->tsnap.snapTarget, loc); + copy_v3_v3(t->tsnap.snapTarget, loc); closest = td; t->tsnap.dist = dist; } @@ -993,13 +993,13 @@ void TargetSnapClosest(TransInfo *t) float loc[3]; float dist; - VECCOPY(loc, td->center); + copy_v3_v3(loc, td->center); dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint); if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist)) { - VECCOPY(t->tsnap.snapTarget, loc); + copy_v3_v3(t->tsnap.snapTarget, loc); closest = td; t->tsnap.dist = dist; } @@ -1014,7 +1014,7 @@ void TargetSnapClosest(TransInfo *t) float loc[3]; float dist; - VECCOPY(loc, td->center); + copy_v3_v3(loc, td->center); if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; @@ -1025,7 +1025,7 @@ void TargetSnapClosest(TransInfo *t) if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist)) { - VECCOPY(t->tsnap.snapTarget, loc); + copy_v3_v3(t->tsnap.snapTarget, loc); closest = td; t->tsnap.dist = dist; } @@ -1052,11 +1052,11 @@ static int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], fl int screen_loc[2]; int new_dist; - VECCOPY(intersect, ray_normal_local); + copy_v3_v3(intersect, ray_normal_local); mul_v3_fl(intersect, lambda); add_v3_v3(intersect, ray_start_local); - VECCOPY(location, intersect); + copy_v3_v3(location, intersect); if (v4co) normal_quad_v3( normal,v1co, v2co, v3co, v4co); @@ -1075,8 +1075,8 @@ static int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], fl *depth = new_depth; retval = 1; - VECCOPY(loc, location); - VECCOPY(no, normal); + copy_v3_v3(loc, location); + copy_v3_v3(no, normal); mul_m3_v3(timat, no); normalize_v3(no); @@ -1095,7 +1095,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh int result; int retval = 0; - VECCOPY(ray_end, ray_normal_local); + copy_v3_v3(ray_end, ray_normal_local); mul_v3_fl(ray_end, 2000); add_v3_v3v3(ray_end, ray_start_local, ray_end); @@ -1116,11 +1116,11 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh if (mul > 1) { mul = 1; - VECCOPY(intersect, v1co); + copy_v3_v3(intersect, v1co); } else if (mul < 0) { mul = 0; - VECCOPY(intersect, v2co); + copy_v3_v3(intersect, v2co); } if (dot_v3v3(ray_normal_local, dvec) > 0) @@ -1130,7 +1130,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh int screen_loc[2]; int new_dist; - VECCOPY(location, intersect); + copy_v3_v3(location, intersect); mul_m4_v3(obmat, location); @@ -1164,7 +1164,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh normalize_v3(no); } - VECCOPY(loc, location); + copy_v3_v3(loc, location); *dist = new_dist; } @@ -1188,7 +1188,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], fl int screen_loc[2]; int new_dist; - VECCOPY(location, vco); + copy_v3_v3(location, vco); mul_m4_v3(obmat, location); @@ -1202,7 +1202,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], fl *depth = new_depth; retval = 1; - VECCOPY(loc, location); + copy_v3_v3(loc, location); if (no) { @@ -1226,8 +1226,8 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm invert_m4_m4(imat, obmat); - VECCOPY(ray_start_local, ray_start); - VECCOPY(ray_normal_local, ray_normal); + copy_v3_v3(ray_start_local, ray_start); + copy_v3_v3(ray_normal_local, ray_normal); mul_m4_v3(imat, ray_start_local); mul_mat3_m4_v3(imat, ray_normal_local); @@ -1300,8 +1300,8 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh copy_m3_m4(timat, imat); transpose_m3(timat); - VECCOPY(ray_start_local, ray_start); - VECCOPY(ray_normal_local, ray_normal); + copy_v3_v3(ray_start_local, ray_start); + copy_v3_v3(ray_normal_local, ray_normal); mul_m4_v3(imat, ray_start_local); mul_mat3_m4_v3(imat, ray_normal_local); @@ -1699,8 +1699,8 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n peel->depth = depth; peel->ob = ob; - VECCOPY(peel->p, p); - VECCOPY(peel->no, no); + copy_v3_v3(peel->p, p); + copy_v3_v3(peel->no, no); BLI_addtail(depth_peels, peel); @@ -1724,8 +1724,8 @@ static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float copy_m3_m4(timat, imat); transpose_m3(timat); - VECCOPY(ray_start_local, ray_start); - VECCOPY(ray_normal_local, ray_normal); + copy_v3_v3(ray_start_local, ray_start); + copy_v3_v3(ray_normal_local, ray_normal); mul_m4_v3(imat, ray_start_local); mul_mat3_m4_v3(imat, ray_normal_local); @@ -1757,11 +1757,11 @@ static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float float intersect[3]; float new_depth; - VECCOPY(intersect, ray_normal_local); + copy_v3_v3(intersect, ray_normal_local); mul_v3_fl(intersect, lambda); add_v3_v3(intersect, ray_start_local); - VECCOPY(location, intersect); + copy_v3_v3(location, intersect); if (f->v4) normal_quad_v3( normal,verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co); @@ -1787,11 +1787,11 @@ static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float float intersect[3]; float new_depth; - VECCOPY(intersect, ray_normal_local); + copy_v3_v3(intersect, ray_normal_local); mul_v3_fl(intersect, lambda); add_v3_v3(intersect, ray_start_local); - VECCOPY(location, intersect); + copy_v3_v3(location, intersect); if (f->v4) normal_quad_v3( normal,verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co); diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript index a694b211ca4..cfbc735eb5c 100644 --- a/source/blender/editors/util/SConscript +++ b/source/blender/editors/util/SConscript @@ -8,4 +8,4 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../makesrna' incs += ' ../../blenloader' -env.BlenderLib ( 'bf_editors_util', sources, Split(incs), [], libtype=['core'], priority=[130] ) +env.BlenderLib ( 'bf_editors_util', sources, Split(incs), [], libtype=['core','player'], priority=[330,210] ) diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index d0c7f9d494f..5a1c0c537c0 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -126,6 +126,7 @@ GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex); int GPU_texture_target(GPUTexture *tex); int GPU_texture_opengl_width(GPUTexture *tex); int GPU_texture_opengl_height(GPUTexture *tex); +int GPU_texture_opengl_bindcode(GPUTexture *tex); /* GPU Framebuffer - this is a wrapper for an OpenGL framebuffer object (FBO). in practice @@ -179,6 +180,7 @@ typedef struct GPUVertexAttribs { int type; int glindex; int gltexco; + int attribid; char name[32]; } layer[GPU_MAX_ATTRIB]; diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f563d8cbe92..95a08e6d5b3 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -37,6 +37,8 @@ #ifndef __GPU_MATERIAL__ #define __GPU_MATERIAL__ +#include "DNA_listBase.h" + #ifdef __cplusplus extern "C" { #endif @@ -46,6 +48,7 @@ struct ImageUser; struct Material; struct Object; struct Lamp; +struct Image; struct bNode; struct LinkNode; struct Scene; @@ -72,7 +75,6 @@ typedef enum GPUType { GPU_VEC4 = 4, GPU_MAT3 = 9, GPU_MAT4 = 16, - GPU_TEX1D = 1001, GPU_TEX2D = 1002, GPU_SHADOW2D = 1003, GPU_ATTRIB = 3001 @@ -107,10 +109,10 @@ typedef struct GPUNodeStack { GPUNodeLink *GPU_attribute(int type, const char *name); GPUNodeLink *GPU_uniform(float *num); -GPUNodeLink *GPU_dynamic_uniform(float *num); +GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data); GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser); GPUNodeLink *GPU_texture(int size, float *pixels); -GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex); +GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data); GPUNodeLink *GPU_socket(GPUNodeStack *sock); GPUNodeLink *GPU_builtin(GPUBuiltin builtin); @@ -153,6 +155,72 @@ typedef struct GPUShadeResult { void GPU_shadeinput_set(GPUMaterial *mat, struct Material *ma, GPUShadeInput *shi); void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr); +/* Export GLSL shader */ + +typedef enum GPUDynamicType { + GPU_DYNAMIC_NONE = 0, + GPU_DYNAMIC_OBJECT_VIEWMAT = 1, + GPU_DYNAMIC_OBJECT_MAT = 2, + GPU_DYNAMIC_OBJECT_VIEWIMAT = 3, + GPU_DYNAMIC_OBJECT_IMAT = 4, + GPU_DYNAMIC_OBJECT_COLOR = 5, + GPU_DYNAMIC_LAMP_FIRST = 6, + GPU_DYNAMIC_LAMP_DYNVEC = 6, + GPU_DYNAMIC_LAMP_DYNCO = 7, + GPU_DYNAMIC_LAMP_DYNIMAT = 8, + GPU_DYNAMIC_LAMP_DYNPERSMAT = 9, + GPU_DYNAMIC_LAMP_DYNENERGY = 10, + GPU_DYNAMIC_LAMP_DYNCOL = 11, + GPU_DYNAMIC_LAMP_LAST = 11, + GPU_DYNAMIC_SAMPLER_2DBUFFER = 12, + GPU_DYNAMIC_SAMPLER_2DIMAGE = 13, + GPU_DYNAMIC_SAMPLER_2DSHADOW = 14, +} GPUDynamicType; + +typedef enum GPUDataType { + GPU_DATA_NONE = 0, + GPU_DATA_1I = 1, // 1 integer + GPU_DATA_1F = 2, + GPU_DATA_2F = 3, + GPU_DATA_3F = 4, + GPU_DATA_4F = 5, + GPU_DATA_9F = 6, + GPU_DATA_16F = 7, + GPU_DATA_4UB = 8, +} GPUDataType; + +/* this structure gives information of each uniform found in the shader */ +typedef struct GPUInputUniform { + struct GPUInputUniform *next, *prev; + char varname[32]; /* name of uniform in shader */ + GPUDynamicType type; /* type of uniform, data format and calculation derive from it */ + GPUDataType datatype; /* type of uniform data */ + struct Object *lamp; /* when type=GPU_DYNAMIC_LAMP_... or GPU_DYNAMIC_SAMPLER_2DSHADOW */ + struct Image *image; /* when type=GPU_DYNAMIC_SAMPLER_2DIMAGE */ + int texnumber; /* when type=GPU_DYNAMIC_SAMPLER, texture number: 0.. */ + unsigned char *texpixels; /* for internally generated texture, pixel data in RGBA format */ + int texsize; /* size in pixel of the texture in texpixels buffer: for 2D textures, this is S and T size (square texture) */ +} GPUInputUniform; + +typedef struct GPUInputAttribute { + struct GPUInputAttribute *next, *prev; + char varname[32]; /* name of attribute in shader */ + int type; /* from CustomData.type, data type derives from it */ + GPUDataType datatype; /* type of attribute data */ + const char *name; /* layer name */ + int number; /* generic attribute number */ +} GPUInputAttribute; + +typedef struct GPUShaderExport { + ListBase uniforms; + ListBase attributes; + char *vertex; + char *fragment; +} GPUShaderExport; + +GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma); +void GPU_free_shader_export(GPUShaderExport *shader); + /* Lamps */ GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 360f3dbf63f..b47f6687720 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -64,101 +64,9 @@ extern char datatoc_gpu_shader_vertex_glsl[]; /* structs and defines */ -typedef enum GPUDataSource { - GPU_SOURCE_VEC_UNIFORM, - GPU_SOURCE_BUILTIN, - GPU_SOURCE_TEX_PIXEL, - GPU_SOURCE_TEX, - GPU_SOURCE_ATTRIB -} GPUDataSource; - static const char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4", NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4"}; -struct GPUNode { - struct GPUNode *next, *prev; - - const char *name; - int tag; - - ListBase inputs; - ListBase outputs; -}; - -struct GPUNodeLink { - GPUNodeStack *socket; - - int attribtype; - const char *attribname; - - int image; - - int texture; - int texturesize; - - void *ptr1, *ptr2; - - int dynamic; - - int type; - int users; - - GPUTexture *dynamictex; - - GPUBuiltin builtin; - - struct GPUOutput *output; -}; - -typedef struct GPUOutput { - struct GPUOutput *next, *prev; - - GPUNode *node; - int type; /* data type = length of vector/matrix */ - GPUNodeLink *link; /* output link */ - int id; /* unique id as created by code generator */ -} GPUOutput; - -typedef struct GPUInput { - struct GPUInput *next, *prev; - - GPUNode *node; - - int type; /* datatype */ - int source; /* data source */ - - int id; /* unique id as created by code generator */ - int texid; /* number for multitexture */ - int attribid; /* id for vertex attributes */ - int bindtex; /* input is responsible for binding the texture? */ - int definetex; /* input is responsible for defining the pixel? */ - int textarget; /* GL_TEXTURE_* */ - int textype; /* datatype */ - - struct Image *ima; /* image */ - struct ImageUser *iuser;/* image user */ - float *dynamicvec; /* vector data in case it is dynamic */ - GPUTexture *tex; /* input texture, only set at runtime */ - int shaderloc; /* id from opengl */ - char shadername[32]; /* name in shader */ - - float vec[16]; /* vector data */ - GPUNodeLink *link; - int dynamictex; /* dynamic? */ - int attribtype; /* attribute type */ - char attribname[32]; /* attribute name */ - int attribfirst; /* this is the first one that is bound */ - GPUBuiltin builtin; /* builtin uniform */ -} GPUInput; - -struct GPUPass { - struct GPUPass *next, *prev; - - ListBase inputs; - struct GPUOutput *output; - struct GPUShader *shader; -}; - /* GLSL code parsing for finding function definitions. * These are stored in a hash for lookup when creating a material. */ @@ -185,7 +93,7 @@ static char *gpu_str_skip_token(char *str, char *token, int max) /* skip a variable/function name */ while(*str) { - if(ELEM6(*str, ' ', '(', ')', ',', '\t', '\n')) + if(ELEM7(*str, ' ', '(', ')', ',', '\t', '\n', '\r')) break; else { if(token && len < max-1) { @@ -203,7 +111,7 @@ static char *gpu_str_skip_token(char *str, char *token, int max) /* skip the next special characters: * note the missing ')' */ while(*str) { - if(ELEM5(*str, ' ', '(', ',', '\t', '\n')) + if(ELEM6(*str, ' ', '(', ',', '\t', '\n', '\r')) str++; else break; @@ -245,8 +153,6 @@ static void gpu_parse_functions_string(GHash *hash, char *code) if(!type && gpu_str_prefix(code, "sampler2DShadow")) type= GPU_SHADOW2D; - if(!type && gpu_str_prefix(code, "sampler1D")) - type= GPU_TEX1D; if(!type && gpu_str_prefix(code, "sampler2D")) type= GPU_TEX2D; @@ -298,9 +204,7 @@ static char *gpu_generate_function_prototyps(GHash *hash) else if(function->paramqual[a] == FUNCTION_QUAL_INOUT) BLI_dynstr_append(ds, "inout "); - if(function->paramtype[a] == GPU_TEX1D) - BLI_dynstr_append(ds, "sampler1D"); - else if(function->paramtype[a] == GPU_TEX2D) + if(function->paramtype[a] == GPU_TEX2D) BLI_dynstr_append(ds, "sampler2D"); else if(function->paramtype[a] == GPU_SHADOW2D) BLI_dynstr_append(ds, "sampler2DShadow"); @@ -542,7 +446,6 @@ static void codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes) /* create exactly one sampler for each texture */ if (codegen_input_has_texture(input) && input->bindtex) BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", - (input->textype == GPU_TEX1D)? "sampler1D": (input->textype == GPU_TEX2D)? "sampler2D": "sampler2DShadow", input->texid); } @@ -947,6 +850,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type) input->textarget = GL_TEXTURE_2D; input->textype = type; input->dynamictex = 1; + input->dynamicdata = link->ptr2; MEM_freeN(link); } else if(link->texture) { @@ -955,14 +859,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type) input->source = GPU_SOURCE_TEX; input->textype = type; - if (type == GPU_TEX1D) { - input->tex = GPU_texture_create_1D(link->texturesize, link->ptr1, NULL); - input->textarget = GL_TEXTURE_1D; - } - else { - input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL); - input->textarget = GL_TEXTURE_2D; - } + //input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL); + input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL); + input->textarget = GL_TEXTURE_2D; MEM_freeN(link->ptr1); MEM_freeN(link); @@ -993,8 +892,11 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type) input->source = GPU_SOURCE_VEC_UNIFORM; memcpy(input->vec, link->ptr1, type*sizeof(float)); - if(link->dynamic) + if(link->dynamic) { input->dynamicvec= link->ptr1; + input->dynamictype= link->dynamictype; + input->dynamicdata= link->ptr2; + } MEM_freeN(link); } @@ -1102,12 +1004,12 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a input->attribfirst = 1; attribs->layer[a].type = input->attribtype; - attribs->layer[a].glindex = input->attribid; + attribs->layer[a].attribid = input->attribid; BLI_strncpy(attribs->layer[a].name, input->attribname, sizeof(attribs->layer[a].name)); } else - input->attribid = attribs->layer[a].glindex; + input->attribid = attribs->layer[a].attribid; } } } @@ -1148,13 +1050,15 @@ GPUNodeLink *GPU_uniform(float *num) return link; } -GPUNodeLink *GPU_dynamic_uniform(float *num) +GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data) { GPUNodeLink *link = GPU_node_link_create(0); link->ptr1= num; - link->ptr2= NULL; + link->ptr2= data; link->dynamic= 1; + link->dynamictype = dynamictype; + return link; } @@ -1181,12 +1085,14 @@ GPUNodeLink *GPU_texture(int size, float *pixels) return link; } -GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex) +GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data) { GPUNodeLink *link = GPU_node_link_create(0); link->dynamic = 1; link->dynamictex = tex; + link->dynamictype = dynamictype; + link->ptr2 = data; return link; } @@ -1389,8 +1295,6 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri fragmentcode = code_generate_fragment(nodes, outlink->output, name); vertexcode = code_generate_vertex(nodes); shader = GPU_shader_create(vertexcode, fragmentcode, datatoc_gpu_shader_material_glsl); /*FUNCTION_LIB);*/ - MEM_freeN(fragmentcode); - MEM_freeN(vertexcode); /* failed? */ if (!shader) { @@ -1405,6 +1309,9 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri pass->output = outlink->output; pass->shader = shader; + pass->fragmentcode = fragmentcode; + pass->vertexcode = vertexcode; + pass->libcode = datatoc_gpu_shader_material_glsl; /* extract dynamic inputs and throw away nodes */ GPU_nodes_extract_dynamic_inputs(pass, nodes); @@ -1417,6 +1324,10 @@ void GPU_pass_free(GPUPass *pass) { GPU_shader_free(pass->shader); GPU_inputs_free(&pass->inputs); + if (pass->fragmentcode) + MEM_freeN(pass->fragmentcode); + if (pass->vertexcode) + MEM_freeN(pass->vertexcode); MEM_freeN(pass); } diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index b0a131f5989..1e44eba89d4 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -39,12 +39,15 @@ #define __GPU_CODEGEN_H__ #include "DNA_listBase.h" +#include "GPU_material.h" +#include "GL/glew.h" struct ListBase; struct GPUShader; struct GPUOutput; struct GPUNode; struct GPUVertexAttribs; +struct GPUFrameBuffer; #define MAX_FUNCTION_NAME 64 #define MAX_PARAMETER 32 @@ -68,7 +71,105 @@ GPUFunction *GPU_lookup_function(const char *name); at the end if used. */ -struct GPUPass; +typedef enum GPUDataSource { + GPU_SOURCE_VEC_UNIFORM, + GPU_SOURCE_BUILTIN, + GPU_SOURCE_TEX_PIXEL, + GPU_SOURCE_TEX, + GPU_SOURCE_ATTRIB +} GPUDataSource; + +struct GPUNode { + struct GPUNode *next, *prev; + + const char *name; + int tag; + + ListBase inputs; + ListBase outputs; +}; + +struct GPUNodeLink { + GPUNodeStack *socket; + + int attribtype; + const char *attribname; + + int image; + + int texture; + int texturesize; + + void *ptr1, *ptr2; + + int dynamic; + int dynamictype; + + int type; + int users; + + GPUTexture *dynamictex; + + GPUBuiltin builtin; + + struct GPUOutput *output; +}; + +typedef struct GPUOutput { + struct GPUOutput *next, *prev; + + GPUNode *node; + int type; /* data type = length of vector/matrix */ + GPUNodeLink *link; /* output link */ + int id; /* unique id as created by code generator */ +} GPUOutput; + +typedef struct GPUInput { + struct GPUInput *next, *prev; + + GPUNode *node; + + int type; /* datatype */ + int source; /* data source */ + + int id; /* unique id as created by code generator */ + int texid; /* number for multitexture */ + int attribid; /* id for vertex attributes */ + int bindtex; /* input is responsible for binding the texture? */ + int definetex; /* input is responsible for defining the pixel? */ + int textarget; /* GL_TEXTURE_* */ + int textype; /* datatype */ + + struct Image *ima; /* image */ + struct ImageUser *iuser;/* image user */ + float *dynamicvec; /* vector data in case it is dynamic */ + int dynamictype; /* origin of the dynamic uniform (GPUDynamicType) */ + void *dynamicdata; /* data source of the dynamic uniform */ + GPUTexture *tex; /* input texture, only set at runtime */ + int shaderloc; /* id from opengl */ + char shadername[32]; /* name in shader */ + + float vec[16]; /* vector data */ + GPUNodeLink *link; + int dynamictex; /* dynamic? */ + int attribtype; /* attribute type */ + char attribname[32]; /* attribute name */ + int attribfirst; /* this is the first one that is bound */ + GPUBuiltin builtin; /* builtin uniform */ +} GPUInput; + +struct GPUPass { + struct GPUPass *next, *prev; + + ListBase inputs; + struct GPUOutput *output; + struct GPUShader *shader; + char *fragmentcode; + char *vertexcode; + const char *libcode; +}; + + typedef struct GPUPass GPUPass; GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink, diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index c9f1b093b7a..fb9f21cde8c 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -423,7 +423,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in if (tex->target != GL_TEXTURE_1D) { /* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */ - GLenum wrapmode = (depth)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER; + GLenum wrapmode = (depth || tex->h == 1)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER; glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode); glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode); @@ -685,6 +685,11 @@ int GPU_texture_opengl_height(GPUTexture *tex) return tex->h; } +int GPU_texture_opengl_bindcode(GPUTexture *tex) +{ + return tex->bindcode; +} + GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex) { return tex->fb; diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 15b96b6d808..9aa453af4d6 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -175,7 +175,7 @@ static void gpu_material_set_attrib_id(GPUMaterial *material) * removed by the glsl compiler by dead code elimination */ for(a=0, b=0; a<attribs->totlayer; a++) { - sprintf(name, "att%d", attribs->layer[a].glindex); + sprintf(name, "att%d", attribs->layer[a].attribid); attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); if(attribs->layer[a].glindex >= 0) { @@ -386,12 +386,12 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode /* from get_lamp_visibility */ if(lamp->type==LA_SUN || lamp->type==LA_HEMI) { mat->dynproperty |= DYN_LAMP_VEC; - GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec), lv, dist, &visifac); + GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac); return visifac; } else { mat->dynproperty |= DYN_LAMP_CO; - GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), lv, dist, &visifac); + GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac); if(lamp->type==LA_AREA) return visifac; @@ -426,11 +426,11 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode if(lamp->type == LA_SPOT) { if(lamp->mode & LA_SQUARE) { mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT; - GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec), GPU_dynamic_uniform((float*)lamp->dynimat), *lv, &inpr); + GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), GPU_dynamic_uniform((float*)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), *lv, &inpr); } else { mat->dynproperty |= DYN_LAMP_VEC; - GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec), *lv, &inpr); + GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr); } GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac); @@ -646,7 +646,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la float area[4][4]= {{0.0f}}, areasize= 0.0f; mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO; - GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), GPU_dynamic_uniform(lamp->dynvec), vn, GPU_uniform((float*)area), + GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn, GPU_uniform((float*)area), GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp); } @@ -684,13 +684,13 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la GPU_link(mat, "test_shadowbuf", GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex), - GPU_dynamic_uniform((float*)lamp->dynpersmat), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), GPU_uniform(&lamp->bias), inp, &shadfac); if(lamp->mode & LA_ONLYSHADOW) { GPU_link(mat, "shade_only_shadow", i, shadfac, - GPU_dynamic_uniform(&lamp->dynenergy), &shadfac); + GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), &shadfac); if(!(lamp->mode & LA_NO_DIFF)) GPU_link(mat, "shade_only_shadow_diffuse", shadfac, shi->rgb, @@ -719,7 +719,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) { if(!(lamp->mode & LA_NO_DIFF)) { GPUNodeLink *rgb; - GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol), &rgb); + GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &rgb); add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff); } } @@ -729,7 +729,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) { if(lamp->type == LA_HEMI) { GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t); - GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol); + GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol); GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); } else { @@ -752,11 +752,11 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la if(ma->mode & MA_RAMP_SPEC) { GPUNodeLink *spec; do_specular_ramp(shi, specfac, t, &spec); - GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), spec, &outcol); + GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), spec, &outcol); GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); } else { - GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol); + GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol); GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); } } @@ -1676,3 +1676,187 @@ int GPU_lamp_shadow_layer(GPULamp *lamp) return -1; } +/* export the GLSL shader */ + +GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) +{ + static struct { + GPUBuiltin gputype; + GPUDynamicType dynamictype; + GPUDataType datatype; + } builtins[] = { + { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F }, + { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F }, + { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F }, + { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F }, + { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F }, + { 0 } + }; + + GPUShaderExport *shader = NULL; + GPUPass *pass; + GPUInput *input; + GPUMaterial *mat; + GPUInputUniform *uniform; + GPUInputAttribute *attribute; + GLint lastbindcode; + int i, liblen, fraglen; + + if(!GPU_glsl_support()) + return NULL; + + mat = GPU_material_from_blender(scene, ma); + pass = (mat)? mat->pass: NULL; + + if(pass && pass->fragmentcode && pass->vertexcode) { + shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport"); + + for(input = pass->inputs.first; input; input = input->next) { + uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform"); + + if(input->ima) { + /* image sampler uniform */ + uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE; + uniform->datatype = GPU_DATA_1I; + uniform->image = input->ima; + uniform->texnumber = input->texid; + BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname)); + } + else if(input->tex) { + /* generated buffer */ + uniform->texnumber = input->texid; + uniform->datatype = GPU_DATA_1I; + BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname)); + + switch(input->textype) { + case GPU_SHADOW2D: + uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW; + uniform->lamp = input->dynamicdata; + break; + case GPU_TEX2D: + if(GPU_texture_opengl_bindcode(input->tex)) { + uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode); + glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex)); + uniform->texsize = GPU_texture_opengl_width(input->tex) * GPU_texture_opengl_height(input->tex); + uniform->texpixels = MEM_mallocN(uniform->texsize*4, "RGBApixels"); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels); + glBindTexture(GL_TEXTURE_2D, lastbindcode); + } + break; + } + } + else { + uniform->type = input->dynamictype; + BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname)); + switch(input->type) { + case 1: + uniform->datatype = GPU_DATA_1F; + break; + case 2: + uniform->datatype = GPU_DATA_2F; + break; + case 3: + uniform->datatype = GPU_DATA_3F; + break; + case 4: + uniform->datatype = GPU_DATA_4F; + break; + case 9: + uniform->datatype = GPU_DATA_9F; + break; + case 16: + uniform->datatype = GPU_DATA_16F; + break; + } + + if(uniform->type >= GPU_DYNAMIC_LAMP_FIRST && uniform->type <= GPU_DYNAMIC_LAMP_LAST) + uniform->lamp = input->dynamicdata; + } + + if(uniform->type != GPU_DYNAMIC_NONE) + BLI_addtail(&shader->uniforms, uniform); + else + MEM_freeN(uniform); + } + + /* process builtin uniform */ + for(i=0; builtins[i].gputype; i++) { + if(mat->builtins & builtins[i].gputype) { + uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform"); + uniform->type = builtins[i].dynamictype; + uniform->datatype = builtins[i].datatype; + BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname)); + BLI_addtail(&shader->uniforms, uniform); + } + } + + // now link fragement shader with library shader + // TBD: remove the function that are not used in the main function + liblen = (pass->libcode) ? strlen(pass->libcode) : 0; + fraglen = strlen(pass->fragmentcode); + shader->fragment = (char *)MEM_mallocN(liblen+fraglen+1, "GPUFragShader"); + if(pass->libcode) + memcpy(shader->fragment, pass->libcode, liblen); + memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen); + shader->fragment[liblen+fraglen] = 0; + + // export the attribute + for(i=0; i<mat->attribs.totlayer; i++) { + attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute"); + attribute->type = mat->attribs.layer[i].type; + attribute->number = mat->attribs.layer[i].glindex; + BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid); + + switch(attribute->type) { + case CD_TANGENT: + attribute->datatype = GPU_DATA_4F; + break; + case CD_MTFACE: + attribute->datatype = GPU_DATA_2F; + attribute->name = mat->attribs.layer[i].name; + break; + case CD_MCOL: + attribute->datatype = GPU_DATA_4UB; + attribute->name = mat->attribs.layer[i].name; + break; + case CD_ORCO: + attribute->datatype = GPU_DATA_3F; + break; + } + + if(attribute->datatype != GPU_DATA_NONE) + BLI_addtail(&shader->attributes, attribute); + else + MEM_freeN(attribute); + } + + // export the vertex shader + shader->vertex = BLI_strdup(pass->vertexcode); + } + + return shader; +} + +void GPU_free_shader_export(GPUShaderExport *shader) +{ + GPUInputUniform *uniform; + + if(shader == NULL) + return; + + for(uniform = shader->uniforms.first; uniform; uniform=uniform->next) + if(uniform->texpixels) + MEM_freeN(uniform->texpixels); + + BLI_freelistN(&shader->uniforms); + BLI_freelistN(&shader->attributes); + + if(shader->vertex) + MEM_freeN(shader->vertex); + if(shader->fragment) + MEM_freeN(shader->fragment); + + MEM_freeN(shader); +} + diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl b/source/blender/gpu/intern/gpu_shader_material.glsl index 815b74a1bf4..c5c822d9224 100644 --- a/source/blender/gpu/intern/gpu_shader_material.glsl +++ b/source/blender/gpu/intern/gpu_shader_material.glsl @@ -308,22 +308,22 @@ void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) outdot = -dot(dir, nor); } -void curves_vec(float fac, vec3 vec, sampler1D curvemap, out vec3 outvec) +void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) { - outvec.x = texture1D(curvemap, (vec.x + 1.0)*0.5).x; - outvec.y = texture1D(curvemap, (vec.y + 1.0)*0.5).y; - outvec.z = texture1D(curvemap, (vec.z + 1.0)*0.5).z; + outvec.x = texture2D(curvemap, vec2((vec.x + 1.0)*0.5, 0.0)).x; + outvec.y = texture2D(curvemap, vec2((vec.y + 1.0)*0.5, 0.0)).y; + outvec.z = texture2D(curvemap, vec2((vec.z + 1.0)*0.5, 0.0)).z; if (fac != 1.0) outvec = (outvec*fac) + (vec*(1.0-fac)); } -void curves_rgb(float fac, vec4 col, sampler1D curvemap, out vec4 outcol) +void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol) { - outcol.r = texture1D(curvemap, texture1D(curvemap, col.r).a).r; - outcol.g = texture1D(curvemap, texture1D(curvemap, col.g).a).g; - outcol.b = texture1D(curvemap, texture1D(curvemap, col.b).a).b; + outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r; + outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g; + outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b; if (fac != 1.0) outcol = (outcol*fac) + (col*(1.0-fac)); @@ -635,9 +635,9 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol) outcol.b= col1.b + fac*(2.0*(col2.b) - 1.0); } -void valtorgb(float fac, sampler1D colormap, out vec4 outcol, out float outalpha) +void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha) { - outcol = texture1D(colormap, fac); + outcol = texture2D(colormap, vec2(fac, 0.0)); outalpha = outcol.a; } @@ -1320,9 +1320,9 @@ void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out visifac *= lampdistkw/(lampdistkw + ld2*dist*dist); } -void lamp_falloff_curve(float lampdist, sampler1D curvemap, float dist, out float visifac) +void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac) { - visifac = texture1D(curvemap, dist/lampdist).x; + visifac = texture2D(curvemap, vec2(dist/lampdist, 0.0)).x; } void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac) diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl.c b/source/blender/gpu/intern/gpu_shader_material.glsl.c index 87a8ed65532..b551ee9dda1 100644 --- a/source/blender/gpu/intern/gpu_shader_material.glsl.c +++ b/source/blender/gpu/intern/gpu_shader_material.glsl.c @@ -1,935 +1,939 @@ /* DataToC output of file <gpu_shader_material_glsl> */ -int datatoc_gpu_shader_material_glsl_size= 39789; +int datatoc_gpu_shader_material_glsl_size= 39910; char datatoc_gpu_shader_material_glsl[]= { - 10,102,108,111, 97,116, 32,101,120,112, 95, 98,108, -101,110,100,101,114, 40,102,108,111, 97,116, 32,102, 41, 10,123, 10, 9,114,101,116,117,114,110, 32,112,111,119, 40, 50, 46, 55, - 49, 56, 50, 56, 49, 56, 50, 56, 52, 54, 44, 32,102, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98, 95,116,111, 95,104, -115,118, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, - 9,102,108,111, 97,116, 32, 99,109, 97,120, 44, 32, 99,109,105,110, 44, 32,104, 44, 32,115, 44, 32,118, 44, 32, 99,100,101,108, -116, 97, 59, 10, 9,118,101, 99, 51, 32, 99, 59, 10, 10, 9, 99,109, 97,120, 32, 61, 32,109, 97,120, 40,114,103, 98, 91, 48, 93, - 44, 32,109, 97,120, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,109,105,110, 32, 61, 32, -109,105,110, 40,114,103, 98, 91, 48, 93, 44, 32,109,105,110, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, - 59, 10, 9, 99,100,101,108,116, 97, 32, 61, 32, 99,109, 97,120, 45, 99,109,105,110, 59, 10, 10, 9,118, 32, 61, 32, 99,109, 97, -120, 59, 10, 9,105,102, 32, 40, 99,109, 97,120, 33, 61, 48, 46, 48, 41, 10, 9, 9,115, 32, 61, 32, 99,100,101,108,116, 97, 47, - 99,109, 97,120, 59, 10, 9,101,108,115,101, 32,123, 10, 9, 9,115, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,104, 32, 61, 32, 48, - 46, 48, 59, 10, 9,125, 10, 10, 9,105,102, 32, 40,115, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,104, 32, 61, 32, 48, - 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9, 99, 32, 61, 32, 40,118,101, 99, 51, 40, 99,109, 97,120, 44, - 32, 99,109, 97,120, 44, 32, 99,109, 97,120, 41, 32, 45, 32,114,103, 98, 46,120,121,122, 41, 47, 99,100,101,108,116, 97, 59, 10, - 10, 9, 9,105,102, 32, 40,114,103, 98, 46,120, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 99, 91, 50, 93, 32, 45, 32, 99, - 91, 49, 93, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,114,103, 98, 46,121, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, - 32, 50, 46, 48, 32, 43, 32, 99, 91, 48, 93, 32, 45, 32, 32, 99, 91, 50, 93, 59, 10, 9, 9,101,108,115,101, 32,104, 32, 61, 32, - 52, 46, 48, 32, 43, 32, 99, 91, 49, 93, 32, 45, 32, 99, 91, 48, 93, 59, 10, 10, 9, 9,104, 32, 47, 61, 32, 54, 46, 48, 59, 10, - 10, 9, 9,105,102, 32, 40,104, 60, 48, 46, 48, 41, 10, 9, 9, 9,104, 32, 43, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 10, 9, -111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,104, 44, 32,115, 44, 32,118, 44, 32,114,103, 98, 46,119, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,104,115,118, 95,116,111, 95,114,103, 98, 40,118,101, 99, 52, 32,104,115,118, 44, 32,111,117,116, 32, -118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,105, 44, 32,102, 44, 32,112, 44, 32,113, - 44, 32,116, 44, 32,104, 44, 32,115, 44, 32,118, 59, 10, 9,118,101, 99, 51, 32,114,103, 98, 59, 10, 10, 9,104, 32, 61, 32,104, -115,118, 91, 48, 93, 59, 10, 9,115, 32, 61, 32,104,115,118, 91, 49, 93, 59, 10, 9,118, 32, 61, 32,104,115,118, 91, 50, 93, 59, - 10, 10, 9,105,102, 40,115, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32, -118, 44, 32,118, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,104, 61, 61, 49, 46, 48, 41, 10, 9, - 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 10, 9, 9,104, 32, 42, 61, 32, 54, 46, 48, 59, 10, 9, 9,105, 32, 61, 32, -102,108,111,111,114, 40,104, 41, 59, 10, 9, 9,102, 32, 61, 32,104, 32, 45, 32,105, 59, 10, 9, 9,114,103, 98, 32, 61, 32,118, -101, 99, 51, 40,102, 44, 32,102, 44, 32,102, 41, 59, 10, 9, 9,112, 32, 61, 32,118, 42, 40, 49, 46, 48, 45,115, 41, 59, 10, 9, - 9,113, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42,102, 41, 41, 59, 10, 9, 9,116, 32, 61, 32,118, 42, 40, 49, 46, 48, - 45, 40,115, 42, 40, 49, 46, 48, 45,102, 41, 41, 41, 59, 10, 9, 9, 10, 9, 9,105,102, 32, 40,105, 32, 61, 61, 32, 48, 46, 48, - 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,116, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, - 32, 40,105, 32, 61, 61, 32, 49, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,113, 44, 32,118, 44, 32,112, 41, 59, - 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 50, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, - 40,112, 44, 32,118, 44, 32,116, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 51, 46, 48, 41, 32, -114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,113, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40, -105, 32, 61, 61, 32, 52, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,116, 44, 32,112, 44, 32,118, 41, 59, 10, 9, - 9,101,108,115,101, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,112, 44, 32,113, 41, 59, 10, 9,125, 10, 10, 9, -111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 44, 32,104,115,118, 46,119, 41, 59, 10,125, 10, 10,102,108, -111, 97,116, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, - 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 52, 48, 52, 53, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, - 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 40, 49, 46, 48, 47, 49, 50, 46, 57, 50, 41, 59, 10, 9,101,108,115, -101, 10, 9, 9,114,101,116,117,114,110, 32,112,111,119, 40, 40, 99, 32, 43, 32, 48, 46, 48, 53, 53, 41, 42, 40, 49, 46, 48, 47, - 49, 46, 48, 53, 53, 41, 44, 32, 50, 46, 52, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,108,105,110,101, 97,114,114,103, 98, - 95,116,111, 95,115,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 48, - 51, 49, 51, 48, 56, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, - 99, 32, 42, 32, 49, 50, 46, 57, 50, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, 32, 49, 46, 48, 53, 53, 32, - 42, 32,112,111,119, 40, 99, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 10,125, 10, 10,118,111, -105,100, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114, -111,109, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, - 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, - 59, 10, 9, 99,111,108, 95,116,111, 46,103, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, - 99,111,108, 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,115,114,103, 98, 95,116,111, - 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, - 97, 32, 61, 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,108,105,110,101, 97,114,114,103, - 98, 95,116,111, 95,115,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32,118,101, 99, - 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,108,105,110,101, 97,114,114,103, - 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116,111, 46,103, - 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,103, 41, - 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, - 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95,102,114,111, -109, 46, 97, 59, 10,125, 10, 10, 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, 52, 49, 53, 57, 50, 54, 53, 51, - 53, 56, 57, 55, 57, 51, 50, 51, 56, 52, 54, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 83, 72, 65, 68, 69, 82, - 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,118, 99, -111,108, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118, -101, 99, 52, 32,118, 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 97,116,116,118, 99,111,108, - 46,120, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99, -111,108, 46,122, 47, 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,117,118, 95, 97,116,116, -114,105, 98,117,116,101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 41, 10, -123, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, - 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,103,101,111,109, 40,118,101, 99, 51, - 32, 99,111, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32, -118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,118,101, 99, 52, 32, 97, -116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,108,111, 99, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, - 32,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114, -109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102,114, -111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108,111, 99, 97,108, 32, 61, 32, 99,111, 59, 10, 9,118,105,101,119, 32, 61, 32, -110,111,114,109, 97,108,105,122,101, 40,108,111, 99, 97,108, 41, 59, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101, -119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40,108,111, 99, 97,108, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9, -111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10, 9,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116, -116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110, -111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, - 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40, 97,116,116,118, - 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9,102,114,111,110,116, 98, 97, 99,107, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, - 10,118,111,105,100, 32,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,109, 97,116, 52, 32,109, 97,116, - 44, 32,118,101, 99, 51, 32,109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32,109, 97,120,118,101, 99, 44, 32,102,108,111, 97, -116, 32,100,111,109,105,110, 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, -117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40,109, 97,116, 32, 42, 32,118,101, 99, 52, 40,118, -101, 99, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100,111,109,105,110, 32, 61, 61, 32, 49, 46, 48, 41, - 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118,101, 99, 44, 32,109,105,110,118,101, 99, 41, 59, - 10, 9,105,102, 40,100,111,109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109,105, -110, 40,111,117,116,118,101, 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99, 97,109,101,114, - 97, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,105,101,119, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,100,101,112,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,105, -115,116, 41, 10,123, 10, 9,111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98,115, 40, 99,111, 46,122, 41, 59, 10, 9,111,117, -116,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, 9,111,117,116,118,105,101,119, 32, 61, 32,110, -111,114,109, 97,108,105,122,101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,100,100, 40,102, + 10,102,108,111, 97,116, + 32,101,120,112, 95, 98,108,101,110,100,101,114, 40,102,108,111, 97,116, 32,102, 41, 10,123, 10, 9,114,101,116,117,114,110, 32, +112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 50, 56, 52, 54, 44, 32,102, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114, +103, 98, 95,116,111, 95,104,115,118, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, + 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 99,109, 97,120, 44, 32, 99,109,105,110, 44, 32,104, 44, 32,115, 44, 32, +118, 44, 32, 99,100,101,108,116, 97, 59, 10, 9,118,101, 99, 51, 32, 99, 59, 10, 10, 9, 99,109, 97,120, 32, 61, 32,109, 97,120, + 40,114,103, 98, 91, 48, 93, 44, 32,109, 97,120, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, + 99,109,105,110, 32, 61, 32,109,105,110, 40,114,103, 98, 91, 48, 93, 44, 32,109,105,110, 40,114,103, 98, 91, 49, 93, 44, 32,114, +103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,100,101,108,116, 97, 32, 61, 32, 99,109, 97,120, 45, 99,109,105,110, 59, 10, 10, 9, +118, 32, 61, 32, 99,109, 97,120, 59, 10, 9,105,102, 32, 40, 99,109, 97,120, 33, 61, 48, 46, 48, 41, 10, 9, 9,115, 32, 61, 32, + 99,100,101,108,116, 97, 47, 99,109, 97,120, 59, 10, 9,101,108,115,101, 32,123, 10, 9, 9,115, 32, 61, 32, 48, 46, 48, 59, 10, + 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 10, 9,105,102, 32, 40,115, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, + 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9, 99, 32, 61, 32, 40,118,101, 99, + 51, 40, 99,109, 97,120, 44, 32, 99,109, 97,120, 44, 32, 99,109, 97,120, 41, 32, 45, 32,114,103, 98, 46,120,121,122, 41, 47, 99, +100,101,108,116, 97, 59, 10, 10, 9, 9,105,102, 32, 40,114,103, 98, 46,120, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 99, + 91, 50, 93, 32, 45, 32, 99, 91, 49, 93, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,114,103, 98, 46,121, 61, 61, 99,109, + 97,120, 41, 32,104, 32, 61, 32, 50, 46, 48, 32, 43, 32, 99, 91, 48, 93, 32, 45, 32, 32, 99, 91, 50, 93, 59, 10, 9, 9,101,108, +115,101, 32,104, 32, 61, 32, 52, 46, 48, 32, 43, 32, 99, 91, 49, 93, 32, 45, 32, 99, 91, 48, 93, 59, 10, 10, 9, 9,104, 32, 47, + 61, 32, 54, 46, 48, 59, 10, 10, 9, 9,105,102, 32, 40,104, 60, 48, 46, 48, 41, 10, 9, 9, 9,104, 32, 43, 61, 32, 49, 46, 48, + 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,104, 44, 32,115, 44, 32,118, 44, 32,114,103, + 98, 46,119, 41, 59, 10,125, 10, 10,118,111,105,100, 32,104,115,118, 95,116,111, 95,114,103, 98, 40,118,101, 99, 52, 32,104,115, +118, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,105, 44, 32, +102, 44, 32,112, 44, 32,113, 44, 32,116, 44, 32,104, 44, 32,115, 44, 32,118, 59, 10, 9,118,101, 99, 51, 32,114,103, 98, 59, 10, + 10, 9,104, 32, 61, 32,104,115,118, 91, 48, 93, 59, 10, 9,115, 32, 61, 32,104,115,118, 91, 49, 93, 59, 10, 9,118, 32, 61, 32, +104,115,118, 91, 50, 93, 59, 10, 10, 9,105,102, 40,115, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 32, 61, 32,118, +101, 99, 51, 40,118, 44, 32,118, 44, 32,118, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,104, 61, + 61, 49, 46, 48, 41, 10, 9, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 10, 9, 9,104, 32, 42, 61, 32, 54, 46, 48, 59, + 10, 9, 9,105, 32, 61, 32,102,108,111,111,114, 40,104, 41, 59, 10, 9, 9,102, 32, 61, 32,104, 32, 45, 32,105, 59, 10, 9, 9, +114,103, 98, 32, 61, 32,118,101, 99, 51, 40,102, 44, 32,102, 44, 32,102, 41, 59, 10, 9, 9,112, 32, 61, 32,118, 42, 40, 49, 46, + 48, 45,115, 41, 59, 10, 9, 9,113, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42,102, 41, 41, 59, 10, 9, 9,116, 32, 61, + 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42, 40, 49, 46, 48, 45,102, 41, 41, 41, 59, 10, 9, 9, 10, 9, 9,105,102, 32, 40,105, + 32, 61, 61, 32, 48, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,116, 44, 32,112, 41, 59, 10, 9, 9, +101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 49, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,113, 44, + 32,118, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 50, 46, 48, 41, 32,114,103, 98, + 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,118, 44, 32,116, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, + 61, 32, 51, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,113, 44, 32,118, 41, 59, 10, 9, 9,101,108, +115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 52, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,116, 44, 32,112, + 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,112, 44, 32,113, 41, + 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 44, 32,104,115,118, 46,119, 41, + 59, 10,125, 10, 10,102,108,111, 97,116, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,102,108,111, + 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, 32, 60, 32, 48, 46, 48, 52, 48, 52, 53, 41, 10, 9, 9,114,101,116,117,114, +110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 40, 49, 46, 48, 47, 49, 50, 46, 57, 50, + 41, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, 32,112,111,119, 40, 40, 99, 32, 43, 32, 48, 46, 48, 53, 53, + 41, 42, 40, 49, 46, 48, 47, 49, 46, 48, 53, 53, 41, 44, 32, 50, 46, 52, 41, 59, 10,125, 10, 10,102,108,111, 97,116, 32,108,105, +110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40,102,108,111, 97,116, 32, 99, 41, 10,123, 10, 9,105,102, 40, 99, + 32, 60, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 10, 9, 9,114,101,116,117,114,110, 32, 40, 99, 32, 60, 32, 48, 46, 48, 41, + 63, 32, 48, 46, 48, 58, 32, 99, 32, 42, 32, 49, 50, 46, 57, 50, 59, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114,110, + 32, 49, 46, 48, 53, 53, 32, 42, 32,112,111,119, 40, 99, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, + 59, 10,125, 10, 10,118,111,105,100, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40,118,101, 99, 52, + 32, 99,111,108, 95,102,114,111,109, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99, +111,108, 95,116,111, 46,114, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95, +102,114,111,109, 46,114, 41, 59, 10, 9, 99,111,108, 95,116,111, 46,103, 32, 61, 32,115,114,103, 98, 95,116,111, 95,108,105,110, +101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32, +115,114,103, 98, 95,116,111, 95,108,105,110,101, 97,114,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, + 99,111,108, 95,116,111, 46, 97, 32, 61, 32, 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,108, +105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 95,102,114,111,109, 44, 32, +111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 95,116,111, 41, 10,123, 10, 9, 99,111,108, 95,116,111, 46,114, 32, 61, 32,108, +105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46,114, 41, 59, 10, 9, 99, +111,108, 95,116,111, 46,103, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116,111, 95,115,114,103, 98, 40, 99,111,108, 95, +102,114,111,109, 46,103, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 98, 32, 61, 32,108,105,110,101, 97,114,114,103, 98, 95,116, +111, 95,115,114,103, 98, 40, 99,111,108, 95,102,114,111,109, 46, 98, 41, 59, 10, 9, 99,111,108, 95,116,111, 46, 97, 32, 61, 32, + 99,111,108, 95,102,114,111,109, 46, 97, 59, 10,125, 10, 10, 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, 52, + 49, 53, 57, 50, 54, 53, 51, 53, 56, 57, 55, 57, 51, 50, 51, 56, 52, 54, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 32, 83, 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10, +118,111,105,100, 32,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, + 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, + 97,116,116,118, 99,111,108, 46,120, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, 53, 53, 46, 48, + 44, 32, 97,116,116,118, 99,111,108, 46,122, 47, 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,117,118, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, + 99, 51, 32,117,118, 41, 10,123, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32, +118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,103,101, +111,109, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118,105,101,119,105, +110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116,116,117,118, 44, + 32,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,108,111, 99, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111,117,116, 32,102, +108,111, 97,116, 32,102,114,111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108,111, 99, 97,108, 32, 61, 32, 99,111, 59, 10, 9, +118,105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,111, 99, 97,108, 41, 59, 10, 9,103,108,111, 98, 97,108, + 32, 61, 32, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40,108,111, 99, 97,108, 44, 32, 49, 46, 48, 41, 41, + 46,120,121,122, 59, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10, 9,117,118, 95, 97,116,116,114,105, + 98,117,116,101, 40, 97,116,116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, + 97,108,105,122,101, 40,110,111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111, +114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,118, 99,111,108, 95, 97,116,116,114,105, 98,117, +116,101, 40, 97,116,116,118, 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9,102,114,111,110,116, 98, 97, 99,107, 32, 61, 32, + 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,109, + 97,116, 52, 32,109, 97,116, 44, 32,118,101, 99, 51, 32,109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32,109, 97,120,118,101, + 99, 44, 32,102,108,111, 97,116, 32,100,111,109,105,110, 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40,109, 97,116, 32, 42, + 32,118,101, 99, 52, 40,118,101, 99, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100,111,109,105,110, 32, + 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118,101, 99, 44, 32,109, +105,110,118,101, 99, 41, 59, 10, 9,105,102, 40,100,111,109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, +101, 99, 32, 61, 32,109,105,110, 40,111,117,116,118,101, 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105, +100, 32, 99, 97,109,101,114, 97, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,105, +101,119, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,101,112,116,104, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,111,117,116,100,105,115,116, 41, 10,123, 10, 9,111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98,115, 40, 99,111, 46, +122, 41, 59, 10, 9,111,117,116,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, 9,111,117,116,118, +105,101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116, +104, 95, 97,100,100, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, + 32, 43, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, 97, 99,116, 40,102, 108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 43, 32,118, 97,108, 50, - 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, 97, 99,116, 40,102,108,111, 97,116, 32,118, 97, + 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, 32,118, 97,108, 50, + 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,117,108,116,105,112,108,121, 40,102,108,111, 97,116, 32,118, 97, 108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, - 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111, -105,100, 32,109, 97,116,104, 95,109,117,108,116,105,112,108,121, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, - 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117, -116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, - 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 50, 32, 61, 61, - 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117, -116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, - 95,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, -108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,109, 97,116,104, 95, 99,111,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,115, 40,118, 97,108, 41, 59, 10, -125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,116, 97, -110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,115,105,110, 40,102,108,111, 97,116, 32, -118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97, -108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97, -108, 32, 61, 32, 97,115,105,110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, - 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99,111,115, 40,102,108,111, 97,116, 32,118, 97,108, - 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 32, 60, - 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, - 32, 97, 99,111,115, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, - 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 97,116, 97, -110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,112,111,119, 40,102,108,111, 97,116, 32,118, - 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, -108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, - 61, 32,112,111,119, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97, -108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,111,103, 40,102,108,111, 97,116, 32, -118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, - 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, 32, 32, 38, 38, 32,118, 97,108, 50, 32, 62, 32, - 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40,118, 97,108, 49, 41, 32, 47, 32,108,111,103, 50, - 40,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 61, 32, 48, 46, 48, 59, 10,125, 10, 10, -118,111,105,100, 32,109, 97,116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32, -118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97, -108, 32, 61, 32,109, 97,120, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116, -104, 95,109,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117, -116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109,105,110, 40, -118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,114,111,117,110,100, 40, -102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9, -111,117,116,118, 97,108, 61, 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, 48, 46, 53, 41, 59, 10,125, 10, 10,118,111,105, -100, 32,109, 97,116,104, 95,108,101,115,115, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, - 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, - 40,118, 97,108, 49, 32, 60, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101, -108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, - 95,103,114,101, 97,116,101,114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32, -118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97, -108, 49, 32, 62, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, - 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,113,117,101,101,122,101, - 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105,100,116,104, 44, 32,102,108,111, 97,116, 32, 99, -101,110,116,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, - 97,108, 32, 61, 32, 49, 46, 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 51, 44, 32, - 45, 40, 40,118, 97,108, 45, 99,101,110,116,101,114, 41, 42,119,105,100,116,104, 41, 41, 41, 59, 10,125, 10, 10,118,111,105,100, - 32,118,101, 99, 95,109, 97,116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97, -108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, - 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 49, - 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,125, 10, 10,118,111,105, -100, 32,118,101, 99, 95,109, 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, + 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111, +105,100, 32,109, 97,116,104, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, + 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40, +118, 97,108, 50, 32, 61, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108, +115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111, +105,100, 32,109, 97,116,104, 95,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, 97,108, 41, 59, 10, +125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 99,111,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,115, + 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, 40,102,108,111, 97, +116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, + 97,108, 32, 61, 32,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,115,105,110, + 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, + 9,105,102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, + 9, 9,111,117,116,118, 97,108, 32, 61, 32, 97,115,105,110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117, +116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99,111,115, 40,102,108, +111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, + 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111, +117,116,118, 97,108, 32, 61, 32, 97, 99,111,115, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97, +108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40,102,108,111, 97,116, + 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97, +108, 32, 61, 32, 97,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,112,111,119, 40, +102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, 48, 41, 10, 9, 9, +111,117,116,118, 97,108, 32, 61, 32,112,111,119, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, + 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,111,103, + 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, 32, 32, 38, 38, 32, +118, 97,108, 50, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40,118, 97,108, 49, 41, + 32, 47, 32,108,111,103, 50, 40,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 61, 32, 48, + 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, + 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, + 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,109, 97,116,104, 95,109,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, + 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, + 32, 61, 32,109,105,110, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, + 95,114,111,117,110,100, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, + 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 61, 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, 48, 46, 53, 41, 59, + 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,101,115,115, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97, +108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, + 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 60, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, + 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111, +105,100, 32,109, 97,116,104, 95,103,114,101, 97,116,101,114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, + 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, + 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, + 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, +115,113,117,101,101,122,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105,100,116,104, 44, 32, +102,108,111, 97,116, 32, 99,101,110,116,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10, +123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, 50, 46, 55, 49, 56, + 50, 56, 49, 56, 51, 44, 32, 45, 40, 40,118, 97,108, 45, 99,101,110,116,101,114, 41, 42,119,105,100,116,104, 41, 41, 41, 59, 10, +125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, + 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9, +111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111, +117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, + 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32,118, 49, 44, 32,118, +101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, 32,118, 50, 59, 10, + 9,111,117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40, +111,117,116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, + 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40,118,101, 99, 51, 32, +118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, + 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10, 9, +111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118, +111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,100,111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, + 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117, +116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, 44, 32, 48, 41, 59, + 10, 9,111,117,116,118, 97,108, 32, 61, 32,100,111,116, 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +118,101, 99, 95,109, 97,116,104, 95, 99,114,111,115,115, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, - 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, 32,118, 50, 59, 10, 9,111,117,116,118, 97,108, - 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, - 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,125, 10, 10,118,111, -105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, - 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111, -117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10, 9,111,117,116,118,101, 99, 32, - 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, - 95,109, 97,116,104, 95,100,111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32, + 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, 50, 41, 59, 10, 9, +111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,118,101, 99, 95,109, 97,116,104, 95,110,111,114,109, 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32, 118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, - 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, 44, 32, 48, 41, 59, 10, 9,111,117,116,118, 97, -108, 32, 61, 32,100,111,116, 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116, -104, 95, 99,114,111,115,115, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9, -111,117,116,118,101, 99, 32, 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, 50, 41, 59, 10, 9,111,117,116,118, 97,108, 32, - 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97, -116,104, 95,110,111,114,109, 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117, -116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97, -108, 32, 61, 32,108,101,110,103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105, -122,101, 40,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,101,103, 97,116,101, 40,118, -101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 41, 10,123, 10, 9,111,117,116,118, 32, 61, 32, - 45,118, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,100,105,114, 44, 32,118,101, 99, - 51, 32,110,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114, 44, 32,111,117,116, 32,102,108,111, 97, -116, 32,111,117,116,100,111,116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, 61, 32,100,105,114, 59, 10, 9,111,117,116,100, -111,116, 32, 61, 32, 45,100,111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32, 99,117,114, -118,101,115, 95,118,101, 99, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109, -112,108,101,114, 49, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, - 41, 10,123, 10, 9,111,117,116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, - 97,112, 44, 32, 40,118,101, 99, 46,120, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 41, 46,120, 59, 10, 9,111,117,116,118,101, - 99, 46,121, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 40,118,101, 99, 46,121, - 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 41, 46,121, 59, 10, 9,111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101,120,116, -117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 40,118,101, 99, 46,122, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, - 53, 41, 46,122, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, - 32, 61, 32, 40,111,117,116,118,101, 99, 42,102, 97, 99, 41, 32, 43, 32, 40,118,101, 99, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, - 41, 59, 10, 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, - 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,115, 97,109,112,108,101,114, 49, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32, -111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116, -101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114, -118,101,109, 97,112, 44, 32, 99,111,108, 46,114, 41, 46, 97, 41, 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, -116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117, -114,118,101,109, 97,112, 44, 32, 99,111,108, 46,103, 41, 46, 97, 41, 46,103, 59, 10, 9,111,117,116, 99,111,108, 46, 98, 32, 61, - 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,116,101,120,116,117,114,101, 49, 68, 40, 99, -117,114,118,101,109, 97,112, 44, 32, 99,111,108, 46, 98, 41, 46, 97, 41, 46, 98, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, - 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32, 40,111,117,116, 99,111,108, 42,102, 97, 99, 41, 32, - 43, 32, 40, 99,111,108, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, - 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,118, - 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, - 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 40,118,101, 99, 51, 32, 99,111,108, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111, -108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117, -116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10, -125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,122,101,114,111, 40,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105, -100, 32,115,101,116, 95,118, 97,108,117,101, 95,111,110,101, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, - 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114, -103, 98, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, - 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, - 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, - 32, 61, 32,118,101, 99, 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,108,101,110,100, 40, -102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, - 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, - 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99, -111,108, 49, 44, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, - 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 97,100,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32, -118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111, -117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, - 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 43, - 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, - 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,109,117,108,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, - 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99, -111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, - 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 42, 32, 99,111, -108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, - 10,118,111,105,100, 32,109,105,120, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, - 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111, -108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, - 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, - 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 52, 40,102, 97, 99,109, 41, 32, 43, 32, -102, 97, 99, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 50, 41, 41, 42, 40,118,101, 99, 52, 40, 49, 46, - 48, 41, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, -125, 10, 10,118,111,105,100, 32,109,105,120, 95,111,118,101,114,108, 97,121, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, + 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32, +110,111,114,109, 97,108,105,122,101, 40,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110, +101,103, 97,116,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 41, 10,123, 10, 9, +111,117,116,118, 32, 61, 32, 45,118, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,100, +105,114, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,111,117,116,100,111,116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, 61, 32,100,105,114, + 59, 10, 9,111,117,116,100,111,116, 32, 61, 32, 45,100,111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, 10,125, 10, 10,118, +111,105,100, 32, 99,117,114,118,101,115, 95,118,101, 99, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 51, 32,118, +101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, + 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,120, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, + 53, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10, 9,111,117,116,118,101, 99, 46,121, 32, 61, 32,116,101,120,116,117,114,101, 50, + 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,121, 32, 43, 32, 49, 46, 48, 41, 42, 48, + 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,121, 59, 10, 9,111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101,120,116,117,114,101, + 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 40,118,101, 99, 46,122, 32, 43, 32, 49, 46, 48, 41, 42, + 48, 46, 53, 44, 32, 48, 46, 48, 41, 41, 46,122, 59, 10, 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, + 9, 9,111,117,116,118,101, 99, 32, 61, 32, 40,111,117,116,118,101, 99, 42,102, 97, 99, 41, 32, 43, 32, 40,118,101, 99, 42, 40, + 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10,125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,114,103, 98, 40,102, +108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117, +114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99, +111,108, 46,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, +116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46,114, 44, 32, + 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,101, +120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, + 40, 99,117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40, 99,111,108, 46,103, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, + 48, 46, 48, 41, 41, 46,103, 59, 10, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99, +117,114,118,101,109, 97,112, 44, 32,118,101, 99, 50, 40,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101,109, 97,112, + 44, 32,118,101, 99, 50, 40, 99,111,108, 46, 98, 44, 32, 48, 46, 48, 41, 41, 46, 97, 44, 32, 48, 46, 48, 41, 41, 46, 98, 59, 10, + 10, 9,105,102, 32, 40,102, 97, 99, 32, 33, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32, 40,111,117, +116, 99,111,108, 42,102, 97, 99, 41, 32, 43, 32, 40, 99,111,108, 42, 40, 49, 46, 48, 45,102, 97, 99, 41, 41, 59, 10, 10, 9,111, +117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108, +117,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10, +123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, + 40,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111, +117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 40,118,101, + 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99, +111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,122,101,114,111, + 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 48, + 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118, 97,108,117,101, 95,111,110,101, 40,111,117,116, 32,102,108, +111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, +118,111,105,100, 32,115,101,116, 95,114,103, 98, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97, +108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105, +100, 32,115,101,116, 95,114,103, 98, 97, 95,122,101,114,111, 40,111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, + 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99, 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32, +109,105,120, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32, +118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, + 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99, +111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99, +111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 97,100,100, 40,102, +108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32, +111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, +102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111, +108, 49, 44, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, + 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,109,117,108,116, 40,102,108,111, 97, +116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, + 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, + 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, + 32, 99,111,108, 49, 32, 42, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, + 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, + 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32, +118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, + 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32, +102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, + 52, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 50, 41, + 41, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, + 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,111,118,101,114,108, 97,121, 40,102,108, +111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111, +117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, + 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, + 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117, +116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 42, 61, 32,102, 97, 99,109, + 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111, +108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, + 32, 45, 32, 99,111,108, 50, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9, +105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 42, 61, + 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,101,108,115,101, 10, 9, 9, +111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, + 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, + 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, + 46, 98, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,101,108, +115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, + 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, + 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115,117, 98, 40,102,108,111, 97,116, 32,102, 97, + 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, + 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, + 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, + 49, 32, 45, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, + 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,118, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, 101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, 116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9, -111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, - 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, - 42, 99,111,108, 50, 46,114, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, - 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,114, 41, - 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, -103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, - 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, - 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111, -108, 50, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117, -116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 42, 61, 32,102, 97, 99,109, - 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111, -108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, - 32, 45, 32, 99,111,108, 50, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,109,105,120, 95,115,117, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111, +111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 33, 61, 32, 48, 46, + 48, 41, 32,111,117,116, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, + 99, 42,111,117,116, 99,111,108, 46,114, 47, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 33, 61, + 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, + 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,103, 47, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 50, 46, 98, + 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, + 98, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46, 98, 47, 99,111,108, 50, 46, 98, 59, 10,125, 10, 10,118,111,105,100, + 32,109,105,120, 95,100,105,102,102, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32, +118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, + 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99, +111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 97, 98,115, 40, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 41, 44, + 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111, +105,100, 32,109,105,120, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, + 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, + 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117, +116, 99,111,108, 46,114,103, 98, 32, 61, 32,109,105,110, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, 46,114,103, + 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118, +111,105,100, 32,109,105,120, 95,108,105,103,104,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111, 108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10, 123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9, -111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 44, 32, -102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105, -100, 32,109,105,120, 95,100,105,118, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32, -118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, - 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97, -116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99, -111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46, -114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,114, - 47, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99, -111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111, -108, 46,103, 47, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 50, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,111, -117,116, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99, 42,111,117, -116, 99,111,108, 46, 98, 47, 99,111,108, 50, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,102,102, 40, -102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, - 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, - 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99, -111,108, 49, 44, 32, 97, 98,115, 40, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 41, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117, -116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100, 97,114, -107, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, - 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97, -109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, - 32,109,105,110, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111, -117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108,105, -103,104,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99, -111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99, -108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, - 32, 61, 32,109, 97,120, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, - 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, -100,111,100,103,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, - 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, - 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, - 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, - 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9, - 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, - 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,114, 47,116,109,112, - 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108, -115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, - 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, - 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, - 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116, -109,112, 32, 61, 32,111,117,116, 99,111,108, 46,103, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, - 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, - 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, - 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, - 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, - 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 47,116, -109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, -101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111, -105,100, 32,109,105,120, 95, 98,117,114,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, +111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109, 97,120, 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, 46, +114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, + 10,118,111,105,100, 32,109,105,120, 95,100,111,100,103,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, + 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, + 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, + 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 33, + 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, + 42, 99,111,108, 50, 46,114, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, + 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117, +116, 99,111,108, 46,114, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, + 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, + 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97, +116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9, 9,105,102, 40,116, +109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, +101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,103, 47,116,109,112, 41, 32, 62, 32, 49, + 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, + 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, + 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, + 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111, +117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, +111,117,116, 99,111,108, 46, 98, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, + 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, + 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,117,114,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, + 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32, +111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, + 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,116,109,112, 44, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32, +102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, + 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, + 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, + 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 47,116,109,112, 41, 41, + 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32, +105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, + 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, 32, 61, 32, +102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, + 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116, +109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 47,116,109,112, + 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115, +101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, + 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, 32, + 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, + 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, + 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 47,116, +109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101, +108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, + 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, 59, 10,125, 10, 10,118, +111,105,100, 32,109,105,120, 95,104,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108, -111, 97,116, 32,116,109,112, 44, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, - 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99, -111,108, 50, 46,114, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, -114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, - 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9, -111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, - 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117, -116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, - 42, 99,111,108, 50, 46,103, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111, -108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, - 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, - 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, - 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9, -111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, - 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, - 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, - 48, 32, 45, 32, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, - 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, - 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, - 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,104,117, -101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, +111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, + 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114, +103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, + 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, + 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 95, +116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109, +105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, + 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 97,116, 40,102,108, +111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111, +117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, + 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, + 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32, +104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104, +115,118, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95, +116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,102, + 97, 99,109, 42,104,115,118, 46,121, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, + 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105, +120, 95,118, 97,108, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, + 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, + 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, + 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, + 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 49, 44, 32,104,115,118, 41, 59, 10, 9,114,103, 98, 95,116, +111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,104,115,118, 46,122, 32, 61, 32,102, 97, 99, +109, 42,104,115,118, 46,122, 32, 43, 32,102, 97, 99, 42,104,115,118, 50, 46,122, 59, 10, 9,104,115,118, 95,116,111, 95,114,103, + 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 99,111,108,111, +114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97, 109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118, 101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9, -104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, - 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, - 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, - 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115, 97,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118, -101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117, -116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, - 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9, -111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, - 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,105,102, 40, -104,115,118, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, - 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,121, 32, - 43, 32,102, 97, 99, 42,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32, -111,117,116, 99,111,108, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,118, 97,108, 40,102,108,111, 97, -116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, - 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, - 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, - 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95, -104,115,118, 40, 99,111,108, 49, 44, 32,104,115,118, 41, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, - 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,104,115,118, 46,122, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,122, 32, 43, 32, -102, 97, 99, 42,104,115,118, 50, 46,122, 59, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, - 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 99,111,108,111,114, 40,102,108,111, 97,116, 32,102, 97, - 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, - 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, - 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, - 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104, -115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, - 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116, -111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115, -118, 50, 46,120, 59, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, - 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, - 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, - 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,115,111,102,116, 40,102,108,111, - 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117, -116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, - 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, - 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,111,110,101, 61, 32,118,101, 99, 52, 40, 49, 46, 48, 41, 59, 10, 9,118, -101, 99, 52, 32,115, 99,114, 61, 32,111,110,101, 32, 45, 32, 40,111,110,101, 32, 45, 32, 99,111,108, 50, 41, 42, 40,111,110,101, - 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,102, 97, 99,109, 42, 99,111,108, 49, 32, 43, 32, -102, 97, 99, 42, 40, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 42, 99,111,108, 50, 42, 99,111,108, 49, 32, 43, 32, 99,111, -108, 49, 42,115, 99,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108,105,110,101, 97,114, 40,102,108,111, 97, -116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, - 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, - 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9, -105,102, 40, 99,111,108, 50, 46,114, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, - 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, - 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, - 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,103, - 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, - 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111, -117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, - 46,103, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46, 98, 32, 62, 32, 48, 46, 53, 41, 10, 9, - 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111, -108, 50, 46, 98, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, - 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 41, 32, 45, 32, 49, 46, 48, - 41, 59, 10,125, 10, 10,118,111,105,100, 32,118, 97,108,116,111,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,115, - 97,109,112,108,101,114, 49, 68, 32, 99,111,108,111,114,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99, -111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, 97,108,112,104, 97, 41, 10,123, 10, 9,111,117,116, 99,111, -108, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,111,108,111,114,109, 97,112, 44, 32,102, 97, 99, 41, 59, 10, 9,111, -117,116, 97,108,112,104, 97, 32, 61, 32,111,117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98,116, -111, 98,119, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, - 41, 32, 32, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32, 99, -111,108,111,114, 46,103, 42, 48, 46, 52, 53, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 32, 47, 42, 32,107,101, -101,112, 32,116,104,101,115,101, 32,102, 97, 99,116,111,114,115, 32,105,110, 32,115,121,110, 99, 32,119,105,116,104, 32,116,101, -120,116,117,114,101, 46,104, 58, 82, 71, 66, 84, 79, 66, 87, 32, 42, 47, 10,125, 10, 10,118,111,105,100, 32,105,110,118,101,114, -116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32, -111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,120,121,122, 32, 61, 32,109,105,120, 40, 99,111,108, 46, -120,121,122, 44, 32,118,101, 99, 51, 40, 49, 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 46,120, -121,122, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,111,108, 46,119, 59, 10,125, 10, 10, -118,111,105,100, 32,104,117,101, 95,115, 97,116, 40,102,108,111, 97,116, 32,104,117,101, 44, 32,102,108,111, 97,116, 32,115, 97, -116, 44, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, - 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,104,115, -118, 59, 10, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,104,115,118, - 91, 48, 93, 32, 43, 61, 32, 40,104,117,101, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102, 40,104,115,118, 91, 48, 93, 62, 49, - 46, 48, 41, 32,104,115,118, 91, 48, 93, 45, 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 48, 93, 60, - 48, 46, 48, 41, 32,104,115,118, 91, 48, 93, 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118, 91, 49, 93, 32, 42, 61, 32,115, 97, -116, 59, 10, 9,105,102, 40,104,115,118, 91, 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 49, 46, 48, 59, 32, -101,108,115,101, 32,105,102, 40,104,115,118, 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 48, 46, 48, 59, - 10, 9,104,115,118, 91, 50, 93, 32, 42, 61, 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,104,115,118, 91, 50, 93, 62, 49, 46, - 48, 41, 32,104,115,118, 91, 50, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 50, 93, 60, 48, - 46, 48, 41, 32,104,115,118, 91, 50, 93, 61, 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115, -118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 44, 32, -111,117,116, 99,111,108, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,112, 97,114, 97,116,101, 95,114, -103, 98, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,114, 32, 61, 32, 99,111,108, 46,114, - 59, 10, 9,103, 32, 61, 32, 99,111,108, 46,103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105, -100, 32, 99,111,109, 98,105,110,101, 95,114,103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,102,108,111, 97,116, 32,103, 44, 32, -102,108,111, 97,116, 32, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,123, 10, 9, 99,111,108, 32, 61, 32, -118,101, 99, 52, 40,114, 44, 32,103, 44, 32, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,111,117,116,112, -117,116, 95,110,111,100,101, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111, -117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, - 40,114,103, 98, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 32, 84, 69, 88, 84, 85, 82, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105, -100, 32,116,101,120,116,117,114,101, 95,102,108,105,112, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 46, -121,120,122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,108,105,110, 40,118, -101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117, -116,118, 97,108, 32, 61, 32, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32, -116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,113,117, 97,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, - 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40, 40, - 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 42, 61, - 32,111,117,116,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,119,111,111,100, 95,115,105, -110, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, - 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, - 9,102,108,111, 97,116, 32, 97, 32, 61, 32,115,113,114,116, 40,118,101, 99, 46,120, 42,118,101, 99, 46,120, 32, 43, 32,118,101, - 99, 46,121, 42,118,101, 99, 46,121, 32, 43, 32,118,101, 99, 46,122, 42,118,101, 99, 46,122, 41, 42, 50, 48, 46, 48, 59, 10, 9, -102,108,111, 97,116, 32,119,105, 32, 61, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,110, 40, 97, 41, 59, 10, 10, 9,118, - 97,108,117,101, 32, 61, 32,119,105, 59, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,119,105, 44, 32,119,105, 44, - 32,119,105, 44, 32, 49, 46, 48, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, - 46, 48, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,105,109, 97,103,101, 40, -118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, - 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, -105,109, 97, 44, 32, 40,118,101, 99, 46,120,121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 41, 42, 48, - 46, 53, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,114,109, 97,108, 46,120, 32, 61, 32, - 50, 46, 48, 42, 40, 99,111,108,111,114, 46,114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,111,114,109, 97,108, 46,121, 32, 61, - 32, 50, 46, 48, 42, 40, 48, 46, 53, 32, 45, 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,110,111,114,109, 97,108, 46,122, 32, - 61, 32, 50, 46, 48, 42, 40, 99,111,108,111,114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 32, 77, 84, 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, - 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,111,114, 99,111, 40,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32, -111,117,116, 32,118,101, 99, 51, 32,111,114, 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, - 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,117,118, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,108,101,100, 32,102,111,114, 32,110, -111,119, 44, 32,119,111,114,107,115, 32,116,111,103,101,116,104,101,114, 32,119,105,116,104, 32,108,101, 97,118,105,110,103, 32, -111,117,116, 32,109,116,101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 10, 9, 32, 32, 32,117,118, 32, 61, 32,118,101, 99, - 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, - 48, 41, 59, 32, 42, 47, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 44, 32, 48, 46, 48, 41, 59, 10,125, - 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 99,111,114,114,101,115,112, -111,110,100,115, 32,116,111, 32,115,104,105, 45, 62,111,114,110, 44, 32,119,104,105, 99,104, 32,105,115, 32,110,101,103, 97,116, -101,100, 32,115,111, 32, 99, 97,110, 99,101,108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,108,101,110,100,101,114, 32,110,111, -114,109, 97,108, 32,110,101,103, 97,116,105,111,110, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111, -114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,116, - 97,110,103,101,110,116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117, -116,116, 97,110,103,101,110,116, 41, 10,123, 10, 9,111,117,116,116, 97,110,103,101,110,116, 32, 61, 32,110,111,114,109, 97,108, -105,122,101, 40,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95, -103,108,111, 98, 97,108, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, - 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118, -105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10,125, 10, - 10,118,111,105,100, 32,116,101,120, 99,111, 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, - 97,116, 44, 32,109, 97,116, 52, 32,111, 98,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32, -118,101, 99, 51, 32,111, 98,106,101, 99,116, 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111, 98,105,110,118,109, - 97,116, 42, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 41, 46,120, -121,122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51, 32,118,110, 44, 32, -118,101, 99, 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10, 9,114,101,102, 32, - 61, 32,118,105,101,119, 32, 45, 32, 50, 46, 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,118,110, 59, 10,125, - 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111, -117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,101,110,100,101,114, - 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,111,117, -116,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, - 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, - 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, -102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, - 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32, -102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,109,117, -108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97, -116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99, -111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99, -103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, 40, -102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, - 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, - 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, - 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, - 99, 51, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,116,101,120, - 99,111,108, 41, 41, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, - 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, - 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, -102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, - 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105, -110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, - 99,116, 42,116,101,120, 99,111,108, 46,114, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32, - 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101, -120, 99,111,108, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40, -111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99, -111,108, 46,103, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 41, 59, - 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, - 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41, 42, 40, 49, 46, 48, - 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, - 53, 41, 10, 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97, 99,109, 32, 43, 32, - 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111, -108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, - 48, 32, 45, 32,116,101,120, 99,111,108, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,111,117,116, 99,111, -108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97, -116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, - 32, 61, 32, 45,102, 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, - 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, - 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, - 32,102, 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, - 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99, -103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, - 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, - 99,116, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46, -114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46, -114, 47,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, - 32,105,110, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99,116, 42, -111,117,116, 99,111,108, 46,103, 47,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46, 98, 32, - 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, - 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105, -100, 32,109,116,101,120, 95,114,103, 98, 95,100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, - 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, - 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99, -116, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, - 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95,114,103, 98, 95,100, 97,114,107, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101, -120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117, -116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, - 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, - 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99, -111,108, 32, 60, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108, -115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, - 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,103, 41, - 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111, -117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9, -105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, - 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95,114,103, 98, 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118, -101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, - 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, -109, 44, 32, 99,111,108, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, - 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, - 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99, -111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111, -108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, - 99,111,108, 46,103, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, - 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111, -108, 46, 98, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, - 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, - 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,111,117,116, 99,111, -108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97, -116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, - 99,111,108, 59, 10, 10, 9,109,105,120, 95,104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111, -117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, - 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, - 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99, -103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, - 10, 9,109,105,120, 95,115, 97,116, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, - 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, - 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109, -116,101,120, 95,114,103, 98, 95,118, 97,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101, -120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117, -116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, - 95,118, 97,108, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, - 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99, -111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114, -103, 98, 95, 99,111,108,111,114, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, +104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,104,115,118, 50, 46,121, + 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117, +116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9, +111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105, +120, 95,115,111,102,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, + 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, + 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, + 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,118,101, 99, 52, 32,111,110,101, 61, 32,118,101, 99, + 52, 40, 49, 46, 48, 41, 59, 10, 9,118,101, 99, 52, 32,115, 99,114, 61, 32,111,110,101, 32, 45, 32, 40,111,110,101, 32, 45, 32, + 99,111,108, 50, 41, 42, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,102, 97, + 99,109, 42, 99,111,108, 49, 32, 43, 32,102, 97, 99, 42, 40, 40,111,110,101, 32, 45, 32, 99,111,108, 49, 41, 42, 99,111,108, 50, + 42, 99,111,108, 49, 32, 43, 32, 99,111,108, 49, 42,115, 99,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108, +105,110,101, 97,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, + 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, + 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, + 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46,114, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, + 99,111,108, 46,114, 61, 32, 99,111,108, 49, 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, + 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 61, 32, 99,111,108, 49, + 46,114, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,114, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, + 9,105,102, 40, 99,111,108, 50, 46,103, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111, +108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 32, 45, 32, 48, 46, 53, 41, 41, 59, + 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 61, 32, 99,111,108, 49, 46,103, 32, 43, 32,102, 97, 99, 42, + 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46,103, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10, 10, 9,105,102, 40, 99,111,108, 50, 46, + 98, 32, 62, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, + 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, 50, 46, 98, 32, 45, 32, 48, 46, 53, 41, 41, 59, 10, 9,101,108,115,101, 10, 9, 9, +111,117,116, 99,111,108, 46, 98, 61, 32, 99,111,108, 49, 46, 98, 32, 43, 32,102, 97, 99, 42, 40, 50, 46, 48, 42, 40, 99,111,108, + 50, 46, 98, 41, 32, 45, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118, 97,108,116,111,114,103, 98, 40,102,108, +111, 97,116, 32,102, 97, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,111,108,111,114,109, 97,112, 44, 32,111,117,116, + 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, 97,108,112,104, 97, + 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,111,108,111,114,109, 97,112, + 44, 32,118,101, 99, 50, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 41, 59, 10, 9,111,117,116, 97,108,112,104, 97, 32, 61, 32,111, +117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,103, 98,116,111, 98,119, 40,118,101, 99, 52, 32, 99,111, +108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 32, 32, 10,123, 10, 9,111,117,116,118, + 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32, 99,111,108,111,114, 46,103, 42, 48, 46, 52, 53, + 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 32, 47, 42, 32,107,101,101,112, 32,116,104,101,115,101, 32,102, 97, + 99,116,111,114,115, 32,105,110, 32,115,121,110, 99, 32,119,105,116,104, 32,116,101,120,116,117,114,101, 46,104, 58, 82, 71, 66, + 84, 79, 66, 87, 32, 42, 47, 10,125, 10, 10,118,111,105,100, 32,105,110,118,101,114,116, 40,102,108,111, 97,116, 32,102, 97, 99, + 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9, +111,117,116, 99,111,108, 46,120,121,122, 32, 61, 32,109,105,120, 40, 99,111,108, 46,120,121,122, 44, 32,118,101, 99, 51, 40, 49, + 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 46,120,121,122, 44, 32,102, 97, 99, 41, 59, 10, 9, +111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,111,108, 46,119, 59, 10,125, 10, 10,118,111,105,100, 32,104,117,101, 95,115, 97, +116, 40,102,108,111, 97,116, 32,104,117,101, 44, 32,102,108,111, 97,116, 32,115, 97,116, 44, 32,102,108,111, 97,116, 32,118, 97, +108,117,101, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, + 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,104,115,118, 59, 10, 10, 9,114,103, 98, 95,116,111, + 95,104,115,118, 40, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,104,115,118, 91, 48, 93, 32, 43, 61, 32, 40,104,117,101, + 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102, 40,104,115,118, 91, 48, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 48, 93, 45, + 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 48, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 48, 93, + 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118, 91, 49, 93, 32, 42, 61, 32,115, 97,116, 59, 10, 9,105,102, 40,104,115,118, 91, + 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, + 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 49, 93, 61, 32, 48, 46, 48, 59, 10, 9,104,115,118, 91, 50, 93, 32, 42, 61, + 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,104,115,118, 91, 50, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 50, 93, 61, 32, + 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 50, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 50, 93, 61, + 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, + 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 44, 32,111,117,116, 99,111,108, 44, 32,102, 97, 99, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,112, 97,114, 97,116,101, 95,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,103, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,114, 32, 61, 32, 99,111,108, 46,114, 59, 10, 9,103, 32, 61, 32, 99,111,108, 46, +103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,109, 98,105,110,101, 95,114, +103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,102,108,111, 97,116, 32,103, 44, 32,102,108,111, 97,116, 32, 98, 44, 32,111,117, +116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,123, 10, 9, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114, 44, 32,103, 44, 32, + 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,111,117,116,112,117,116, 95,110,111,100,101, 40,118,101, 99, + 52, 32,114,103, 98, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, +114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 46,114,103, 98, 44, 32, 97, +108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 84, 69, 88, 84, 85, 82, 69, 83, 32, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,102, +108,105,112, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, +118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 46,121,120,122, 59, 10,125, 10, 10,118,111,105, +100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,108,105,110, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117, +116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 49, 46, 48, + 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101, +110,100, 95,113,117, 97,100, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, + 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, + 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,118, 97,108, 32, 42, 61, 32,111,117,116,118, 97,108, 59, 10,125, 10, + 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,119,111,111,100, 95,115,105,110, 40,118,101, 99, 51, 32,118,101, 99, 44, + 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, + 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 97, 32, 61, 32, +115,113,114,116, 40,118,101, 99, 46,120, 42,118,101, 99, 46,120, 32, 43, 32,118,101, 99, 46,121, 42,118,101, 99, 46,121, 32, 43, + 32,118,101, 99, 46,122, 42,118,101, 99, 46,122, 41, 42, 50, 48, 46, 48, 59, 10, 9,102,108,111, 97,116, 32,119,105, 32, 61, 32, + 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,110, 40, 97, 41, 59, 10, 10, 9,118, 97,108,117,101, 32, 61, 32,119,105, 59, 10, + 9, 99,111,108,111,114, 32, 61, 32,118,101, 99, 52, 40,119,105, 44, 32,119,105, 44, 32,119,105, 44, 32, 49, 46, 48, 41, 59, 10, + 9,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10,125, + 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,115, + 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111, +117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10, +123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 40,118,101, 99, 46,120, +121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 41, 42, 48, 46, 53, 41, 59, 10, 9,118, 97,108,117,101, + 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,114,109, 97,108, 46,120, 32, 61, 32, 50, 46, 48, 42, 40, 99,111,108,111,114, 46, +114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,111,114,109, 97,108, 46,121, 32, 61, 32, 50, 46, 48, 42, 40, 48, 46, 53, 32, 45, + 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,110,111,114,109, 97,108, 46,122, 32, 61, 32, 50, 46, 48, 42, 40, 99,111,108,111, +114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 77, 84, + 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116,101,120, 99, +111, 95,111,114, 99,111, 40,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,114, + 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,116, +101,120, 99,111, 95,117,118, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 41, + 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,108,101,100, 32,102,111,114, 32,110,111,119, 44, 32,119,111,114,107,115, 32,116, +111,103,101,116,104,101,114, 32,119,105,116,104, 32,108,101, 97,118,105,110,103, 32,111,117,116, 32,109,116,101,120, 95, 50,100, + 95,109, 97,112,112,105,110,103, 10, 9, 32, 32, 32,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, + 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 32, 42, 47, 10, 9,117,118, 32, + 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99, +111, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, +110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 99,111,114,114,101,115,112,111,110,100,115, 32,116,111, 32,115,104,105, + 45, 62,111,114,110, 44, 32,119,104,105, 99,104, 32,105,115, 32,110,101,103, 97,116,101,100, 32,115,111, 32, 99, 97,110, 99,101, +108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,108,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,110,101,103, 97,116,105, +111,110, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,110,111,114, +109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,116, 97,110,103,101,110,116, 40,118,101, 99, 52, + 32,116, 97,110,103,101,110,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116, 97,110,103,101,110,116, 41, 10,123, + 10, 9,111,117,116,116, 97,110,103,101,110,116, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,116, 97,110,103,101,110,116, + 46,120,121,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,103,108,111, 98, 97,108, 40,109, 97,116, 52, + 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103, +108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108, 32, 61, 32, 40,118,105,101,119,105,110,118,109, 97,116, 42,118, +101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, + 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,109, 97,116, 52, 32,111, 98, +105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111, 98,106,101, 99,116, + 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111, 98,105,110,118,109, 97,116, 42, 40,118,105,101,119,105,110,118, +109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118,111,105,100, + 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10, 9,114,101,102, 32, 61, 32,118,105,101,119, 32, 45, 32, 50, 46, + 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,118,110, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100, +101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116, +110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111,114, +109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, 45, +110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, +114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99, +111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99, +116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105, +110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, + 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,109,117,108, 40,118,101, 99, 51, 32,111,117,116, 99, +111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, + 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97, +116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, + 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, + 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, + 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, +108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118, +101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, + 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, + 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 51, 40,102, 97, 99,109, 41, 32, 43, 32, +102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40,118,101, 99, 51, + 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, + 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99, +111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99, +116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105, +102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32,111,117, +116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, + 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, + 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,114, 41, 41, 42, 40, 49, + 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, + 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 42, 40,102, 97, 99,109, 32, + 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, + 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, + 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, + 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46, + 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101, +120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, + 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46, + 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, +101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, + 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32, 45,102, 97, 99,116, 42,102, 97, + 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, + 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, 108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118, -101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, 99,111, -108,111,114, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, +101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,102, 97, 99,103, 42, +116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, + 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, + 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, 40,116,101, +120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117, +116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,114, 47,116,101,120, 99,111,108, 46,114, 59, + 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, +102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46,103, 47,116,101, +120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99, +111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99, +111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, +100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102, +108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32, +102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,110, 99,111,108, 32, + 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, + 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,100, 97,114,107, + 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, + 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111, +108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, + 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, + 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, + 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,114, 32, + 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, + 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,103, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, + 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 59, 10, 9, 99, +111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117, +116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111, +108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, + 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, + 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, + 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, 10, 9,102, + 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, + 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32, +111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, + 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101, +120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,103, 41, 32,105,110, 99,111, +108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, + 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, 40, 99,111, +108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32,101,108,115, +101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, +101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, + 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, + 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, +104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111, -108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97, -108,117,101, 95,118, 97,114,115, 40,105,110,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, - 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,109, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, - 61, 32, 97, 98,115, 40,102, 97, 99,103, 41, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, - 9,105,102, 40,102, 97, 99,103, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, -102, 97, 99,116, 59, 10, 9, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,109, 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109, -112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 98,108,101,110,100, 40,102, -108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, - 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99, -111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, - 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, - 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, +108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, + 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, + 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,115, 97,116, 40,102, + 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, + 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, + 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,118, 97,108, + 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, + 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111, +108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,118, 97,108, 40,102, 97, 99,116, 42,102, + 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, + 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111, +108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 99,111,108,111,114, 40,118,101, + 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, + 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10, +123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95, 99,111,108,111,114, 40,102, 97, 99,116, 42,102, 97, + 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99, +111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, + 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,105,110, +111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,102, 97, 99,109, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, 61, 32, 97, 98,115, 40,102, 97, 99,103, 41, + 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, 40,102, 97, 99,103, 32, 60, 32, + 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32,102, 97, 99,116, 59, 10, 9, 9,102, 97, 99, +116, 32, 61, 32,102, 97, 99,109, 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111, +105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, + 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97, +116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97, +116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, + 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111, +108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97, +108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99, +111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32, +102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101, +120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, + 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, + 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111, +105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, 32,111,117,116, 99,111, +108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, + 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, + 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32, +102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, + 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42, 40, 49, + 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, + 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,117, 98, 40,102,108,111, 97,116, 32,111,117,116, 99,111, +108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, + 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, + 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32, +102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32, 45,102, 97, 99,116, 59, 10, 9,105,110, + 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118, +111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, - 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, - 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117, -116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40, -102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97, -116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, - 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95, -118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,109, 32, 61, - 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99, -109, 32, 43, 32,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32, -111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,117, 98, 40, -102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97, -116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, - 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95, -118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, - 32, 45,102, 97, 99,116, 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111, -117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108, -111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32, -102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111, -108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97, -114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32,102, - 97, 99,116, 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99, -111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,118, 40,102,108,111, 97,116, - 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99, -116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10, -123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40, -102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, - 61, 32, 48, 46, 48, 41, 10, 9, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, - 97, 99,116, 42,111,117,116, 99,111,108, 47,116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, - 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40, -102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97, -116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, - 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95, -118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, - 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, - 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100, 97, -114,107, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102, -108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108, -117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, - 97,116, 32, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32, -111,117,116, 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, - 61, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103, -104,116, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102, -108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108, -117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, - 97,116, 32, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32, -111,117,116, 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, - 61, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97, -109,112, 95,112,111,115,105,116,105,118,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, - 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, - 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, - 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116, -102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, - 47, 49, 50, 56, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108, -121, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, -104, 97,114, 41, 10,123, 10, 9,104, 97,114, 32, 42, 61, 32, 49, 50, 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, - 32, 49, 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, - 32, 62, 32, 53, 49, 49, 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32, -111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, - 95,102,114,111,109, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108, -112,104, 97, 41, 10,123, 10, 9, 97,108,112,104, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109, -116,101,120, 95, 97,108,112,104, 97, 95,116,111, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, - 32, 97,108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99, -111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111, -105,100, 32,109,116,101,120, 95,114,103, 98,116,111,105,110,116, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102, -108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100, -111,116, 40,118,101, 99, 51, 40, 48, 46, 51, 53, 44, 32, 48, 46, 52, 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, - 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108, -111, 97,116, 32,105,110,118, 97,108,117,101, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, - 10,123, 10, 9,111,117,116,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, - 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,105,110,118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, - 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118, -101, 99, 52, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,105,110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, - 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40, -102,108,111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32, -111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, -111,117,116,105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110, -116,101,110,115,105,116,121, 59, 10, 9,111,117,116,105,110,116,101,110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105, -116,121, 42,115,116,101,110, 99,105,108, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105, -108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, - 40,102,108,111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108, -111, 97,116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, - 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, - 61, 32,118,101, 99, 52, 40,114,103, 98, 46,114,103, 98, 44, 32,114,103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, - 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118, -111,105,100, 32,109,116,101,120, 95,109, 97,112,112,105,110,103, 95,111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, - 32,118,101, 99, 51, 32,111,102,115, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, - 9,111,117,116,116,101,120, 99,111, 32, 61, 32,116,101,120, 99,111, 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, - 32,109,116,101,120, 95,109, 97,112,112,105,110,103, 95,115,105,122,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118, -101, 99, 51, 32,115,105,122,101, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9, -111,117,116,116,101,120, 99,111, 32, 61, 32,115,105,122,101, 42,116,101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109, -116,101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120, -121, 42, 48, 46, 53, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10, -125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, - 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111, -117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114, -101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,116,101,120, 99,111, - 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, - 41, 10,123, 10, 9, 47, 47, 32, 84,104,101, 32,105,110,118,101,114,116, 32,111,102, 32,116,104,101, 32,114,101,100, 32, 99,104, - 97,110,110,101,108, 32,105,115, 32,116,111, 32,109, 97,107,101, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32, -109, 97,112, 32, 99,111,109,112,108,105, 97,110,116, 32,119,105,116,104, 32,116,104,101, 32,111,117,116,115,105,100,101, 32,119, -111,114,108,100, 46, 10, 9, 47, 47, 32, 73,116, 32,110,101,101,100,115, 32,116,111, 32, 98,101, 32,100,111,110,101, 32, 98,101, - 99, 97,117,115,101, 32,105,110, 32, 66,108,101,110,100,101,114, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32, -117,115,101,100, 32,112,111,105,110,116,115, 32,105,110,119, 97,114,100, 46, 10, 9, 47, 47, 32, 83,104,111,117,108,100, 32,116, -104,105,115, 32,101,118,101,114, 32, 99,104, 97,110,103,101, 32,116,104,105,115, 32,110,101,103, 97,116,101, 32,109,117,115,116, - 32, 98,101, 32,114,101,109,111,118,101,100, 46, 10, 32, 32, 32, 32,118,101, 99, 52, 32, 99,111,108,111,114, 32, 61, 32,116,101, -120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,110,111,114,109, 97,108, 32, - 61, 32, 50, 46, 48, 42, 40,118,101, 99, 51, 40, 45, 99,111,108,111,114, 46,114, 44, 32, 99,111,108,111,114, 46,103, 44, 32, 99, -111,108,111,114, 46, 98, 41, 32, 45, 32,118,101, 99, 51, 40, 45, 48, 46, 53, 44, 32, 48, 46, 53, 44, 32, 48, 46, 53, 41, 41, 59, - 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,110,111,114,109, 97,108,115, 95,105,110,105,116, 40, - 32,118,101, 99, 51, 32,118, 78, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78,111,114,103, 44, 32,111,117,116, 32,118,101, - 99, 51, 32,118, 78, 97, 99, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117, -100,101, 32, 41, 10,123, 10, 9,118, 78,111,114,103, 32, 61, 32,118, 78, 59, 10, 9,118, 78, 97, 99, 99, 32, 61, 32,118, 78, 59, - 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 42, 32,104, -101,108,112,101,114, 32,109,101,116,104,111,100, 32,116,111, 32,101,120,116,114, 97, 99,116, 32,116,104,101, 32,117,112,112,101, -114, 32,108,101,102,116, 32, 51,120, 51, 32,109, 97,116,114,105,120, 32,102,114,111,109, 32, 97, 32, 52,120, 52, 32,109, 97,116, -114,105,120, 32, 42, 47, 10,109, 97,116, 51, 32,116,111, 95,109, 97,116, 51, 40,109, 97,116, 52, 32,109, 52, 41, 10,123, 10, 9, -109, 97,116, 51, 32,109, 51, 59, 10, 9,109, 51, 91, 48, 93, 32, 61, 32,109, 52, 91, 48, 93, 46,120,121,122, 59, 10, 9,109, 51, - 91, 49, 93, 32, 61, 32,109, 52, 91, 49, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 50, 93, 32, 61, 32,109, 52, 91, 50, 93, 46, -120,121,122, 59, 10, 9,114,101,116,117,114,110, 32,109, 51, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117, -109,112, 95,105,110,105,116, 95,111, 98,106,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, - 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,109, 97,116, 52, 32,109, - 86,105,101,119, 44, 32,109, 97,116, 52, 32,109, 86,105,101,119, 73,110,118, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 44, 32, -109, 97,116, 52, 32,109, 79, 98,106, 73,110,118, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80, -114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, - 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100, -101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, - 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,109, 97,116, 51, 32,111, 98,106, 50,118, -105,101,119, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,109, 86,105,101,119, 32, 42, 32,109, 79, 98,106, 41, 59, 10, 9,109, 97, -116, 51, 32,118,105,101,119, 50,111, 98,106, 32, 61, 32,116,111, 95,109, 97,116, 51, 40,109, 79, 98,106, 73,110,118, 32, 42, 32, -109, 86,105,101,119, 73,110,118, 41, 59, 10, 9, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,118,105,101, -119, 50,111, 98,106, 32, 42, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32, -118, 83,105,103,109, 97, 84, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,121, 40, 32,115,117,114,102, 95, -112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,115,117,114, -102, 95,110,111,114,109, 32, 42, 32,111, 98,106, 50,118,105,101,119, 32, 41, 59, 10, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111, -115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, - 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, - 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9, 47, 42, 32,112,114,101,116,114, 97,110,115,102,111,114, -109, 32,118, 78, 97, 99, 99, 32, 40,105,110, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 41, 32,117,115,105, -110,103, 32,116,104,101, 32,105,110,118,101,114,115,101, 32,116,114, 97,110,115,112,111,115,101,100, 32, 42, 47, 10, 9,118, 82, - 49, 32, 61, 32,118, 82, 49, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 82, 50, 32, 61, 32,118, 82, 50, 32, 42, - 32,118,105,101,119, 50,111, 98,106, 59, 10, 9,118, 78, 32, 61, 32,118, 78, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, - 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 32, - 42, 32,108,101,110,103,116,104, 40,118, 78, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, - 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117, -100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, - 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, - 95,116,101,120,116,117,114,101,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, - 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, - 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, - 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116, -117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, - 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, - 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83, -105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32, -118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, - 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, 97,108,105,122,101,100, 32, -105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, - 9,118, 82, 49, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, - 44, 32,118, 78, 32, 41, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115, -115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 41, 59, 10, 9,102, 68,101,116, 32, 61, 32,115,105,103,110, - 40, 32,100,111,116, 40,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 41, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, -102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111, -117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80, -114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100, -101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, - 95, 98,117,109,112, 95,105,110,105,116, 95,118,105,101,119,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95, -112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32, -102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, - 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101, -118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111, -117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, - 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9, -118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, - 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, - 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, - 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97, -108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, - 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, - 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, - 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, - 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105, -116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101, -118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10, -118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 51, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, - 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66, -115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 83, 84,108,108, - 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108,114, 32, 61, 32,116,101,120, 99,111, 46, -120,121, 32, 43, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117,108, - 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9, - 10, 9,102,108,111, 97,116, 32, 72,108,108, 44, 72,108,114, 44, 72,117,108, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116, -101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,108, 41, 44, 32, 72,108,108, 32, 41, 59, 10, 9,114,103, 98, -116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,114, 41, 44, 32, 72,108,114, 32, - 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117,108, - 41, 44, 32, 72,117,108, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,108,114, - 32, 45, 32, 72,108,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117,108, 32, 45, 32, - 72,108,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 53, 40, 32,118,101, - 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, - 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, - 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9, -118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, - 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, - 50, 32, 83, 84, 99, 32, 61, 32,116,101,120, 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, 61, 32,116,101, -120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,114, - 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, - 50, 32, 83, 84,100, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, - 10, 9,118,101, 99, 50, 32, 83, 84,117, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101, -120, 68,121, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72, 99, 44, 72,108, 44, 72,114, 44, 72,100, 44, 72,117, 59, 10, 9, -114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, 99, 41, 44, 32, 72, 99, - 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108, - 41, 44, 32, 72,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, - 44, 32, 83, 84,114, 41, 44, 32, 72,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, - 68, 40,105,109, 97, 44, 32, 83, 84,100, 41, 44, 32, 72,100, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120, -116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, - 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,114, 32, 45, 32, 72,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97, -108,101, 32, 42, 32, 40, 72,117, 32, 45, 32, 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109, -112, 95,100,101,114,105,118, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105, -109, 97, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, 44, 32,102,108, -111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, - 32, 10,123, 10, 9,102,108,111, 97,116, 32,115, 32, 61, 32, 49, 46, 48, 59, 9, 9, 47, 47, 32,110,101,103, 97,116,101, 32,116, -104,105,115, 32,105,102, 32,102,108,105,112,112,101,100, 32,116,101,120,116,117,114,101, 32, 99,111,111,114,100,105,110, 97,116, -101, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, - 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9, 10, - 9, 47, 47, 32,116,104,105,115, 32,118, 97,114,105, 97,110,116, 32,117,115,105,110,103, 32, 97, 32,100,101,114,105,118, 97,116, -105,118,101, 32,109, 97,112, 32,105,115, 32,100,101,115, 99,114,105, 98,101,100, 32,104,101,114,101, 10, 9, 47, 47, 32,104,116, -116,112, 58, 47, 47,109,109,105,107,107,101,108,115,101,110, 51,100, 46, 98,108,111,103,115,112,111,116, 46, 99,111,109, 47, 50, - 48, 49, 49, 47, 48, 55, 47,100,101,114,105,118, 97,116,105,118,101, 45,109, 97,112,115, 46,104,116,109,108, 10, 9,118,101, 99, - 50, 32,100,105,109, 32, 61, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, 95,121, 41, 59, 10, 9,118,101, 99, - 50, 32,100, 66,100,117,118, 32, 61, 32,104, 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, 46, 48, 42,116,101,120,116,117,114, -101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, 46, 48, 41, 59, 10, 9, 10, 9,100, - 66,115, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, - 42, 84,101,120, 68,120, 46,121, 59, 10, 9,100, 66,116, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,121, 46,120, - 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, -101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116, - 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32, -118, 82, 50, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118, -101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117,114, 98,101, -100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105, -103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32,100, 66,115, 32, 42, 32,118, 82, 49, 32, 43, 32,100, 66,116, 32, 42, 32,118, - 82, 50, 32, 41, 59, 10, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32, -118, 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114, -109, 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, -120, 95, 98,117,109,112, 95, 97,112,112,108,121, 95,116,101,120,115,112, 97, 99,101, 40, 32,102,108,111, 97,116, 32,102, 68,101, -116, 44, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, - 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,118,101, 99, 51, 32, -116,101,120, 99,111, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, 44, - 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, - 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117,114, 98,101,100, - 95,110,111,114,109, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101, -120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99, -111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105,103,110, 40,102, - 68,101,116, 41, 32, 42, 32, 40, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,115, 32, 47, 32,108,101,110, -103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,120, 46,120, 44, 32,105,109, 97, 95,121, 42, 84, -101,120, 68,120, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 49, 32, 43, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -100, 66,116, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,121, 46,120, - 44, 32,105,109, 97, 95,121, 42, 84,101,120, 68,121, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 9, 9, 9, - 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, 83,117,114,102, 71,114, - 97,100, 59, 10, 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, - 32,118, 78, 97, 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,101,103, 97,116, -101, 95,116,101,120,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, - 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, - 40, 45,110,111,114,109, 97,108, 46,120, 44, 32, 45,110,111,114,109, 97,108, 46,121, 44, 32,110,111,114,109, 97,108, 46,122, 41, - 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,115,112, 97, 99,101, 95,116, 97,110,103,101,110,116, 40,118,101, - 99, 52, 32,116, 97,110,103,101,110,116, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,116,101, -120,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, -118,101, 99, 51, 32, 66, 32, 61, 32,116, 97,110,103,101,110,116, 46,119, 32, 42, 32, 99,114,111,115,115, 40,110,111,114,109, 97, -108, 44, 32,116, 97,110,103,101,110,116, 46,120,121,122, 41, 59, 10, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,116, -101,120,110,111,114,109, 97,108, 46,120, 42,116, 97,110,103,101,110,116, 46,120,121,122, 32, 43, 32,116,101,120,110,111,114,109, - 97,108, 46,121, 42, 66, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,122, 42,110,111,114,109, 97,108, 59, 10, 9,111,117, -116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10, -125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,108,101,110,100, 95,110,111,114,109, 97,108, 40,102,108,111, 97,116, 32, -110,111,114,102, 97, 99, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,110,101,119,110,111,114, -109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110, -111,114,109, 97,108, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42,110,111,114,109, 97,108, 32, 43, 32, -110,111,114,102, 97, 99, 42,110,101,119,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110, -111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, - 32, 77, 65, 84, 69, 82, 73, 65, 76, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,108, 97,109,112, 95, -118,105,115,105, 98,105,108,105,116,121, 95,115,117,110, 95,104,101,109,105, 40,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, - 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111, -117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32,108, 97,109,112,118,101, - 99, 59, 10, 9,100,105,115,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, -125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,111,116,104,101,114, 40,118,101, - 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, - 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, - 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 9,100,105,115,116, 32, 61, - 32,108,101,110,103,116,104, 40,108,118, 41, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,118, 41, - 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, - 97,108,108,111,102,102, 95,105,110,118,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, - 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10, -123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, - 43, 32,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110, -118,115,113,117, 97,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105, -115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, - 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100,105,115,116, 42,100,105, -115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,115,108,105,100,101,114, -115, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,108,100, 49, 44, 32,102,108,111, - 97,116, 32,108,100, 50, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105, -115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116,107,119, 32, 61, 32,108, 97,109, -112,100,105,115,116, 42,108, 97,109,112,100,105,115,116, 59, 10, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112, -100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,108,100, 49, 42,100,105,115,116, 41, 59, 10, 9,118,105,115, -105,102, 97, 99, 32, 42, 61, 32,108, 97,109,112,100,105,115,116,107,119, 47, 40,108, 97,109,112,100,105,115,116,107,119, 32, 43, - 32,108,100, 50, 42,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97, -108,108,111,102,102, 95, 99,117,114,118,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,115, 97,109,112, -108,101,114, 49, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32, -102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,116,101,120,116, -117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,100,105,115,116, 47,108, 97,109,112,100,105,115,116, 41, 46,120, + 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,116, 59, 10, 9,105,110, 99,111,108, + 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,118, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108, +111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, + 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, + 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, + 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, 61, 32, 48, 46, 48, 41, 10, 9, 9,105,110, + 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 47, +116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10, +118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40,102,108,111, 97,116, 32,111,117,116, 99,111, +108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, + 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, + 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32, +102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99, +111,108, 32, 43, 32,102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10, +125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,111,117, +116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9, +102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99, +116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, 32, 61, 32,102, 97, + 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 41, 32,105,110, 99, +111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99,111,108, 59, 10,125, + 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103,104,116, 40,102,108,111, 97,116, 32,111,117, +116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32, +102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9, +102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99, +116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, 32, 61, 32,102, 97, + 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 41, 32,105,110, 99, +111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99,111,108, 59, 10,125, + 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 95,112,111,115,105,116,105,118,101, + 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, + 9,111,117,116,102, 97, 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, + 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, + 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97, +114, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117, +116,104, 97,114, 41, 10,123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 47, 49, 50, 56, 46, 48, 59, 10,125, 10, 10, +118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108,121, 95, 99,108, 97,109,112, 40,102,108,111, + 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,104, 97,114, + 32, 42, 61, 32, 49, 50, 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, 32, 49, 46, 48, 41, 32,111,117,116,104, 97, +114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, 32, 62, 32, 53, 49, 49, 46, 48, 41, 32,111, +117,116,104, 97,114, 32, 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,111,117,116,104, 97,114, 32, 61, 32,104, 97, +114, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,102,114,111,109, 95, 99,111,108, 40,118, +101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 41, 10,123, 10, 9, 97,108,112, +104, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,116, +111, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, + 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99, +111,108, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, +116,111,105,110,116, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,116,101,110,115, +105,116,121, 41, 10,123, 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100,111,116, 40,118,101, 99, 51, 40, 48, 46, 51, + 53, 44, 32, 48, 46, 52, 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, 98, 41, 59, 10,125, 10, 10,118,111,105,100, + 32,109,116,101,120, 95,118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108,111, 97,116, 32,105,110,118, 97,108,117,101, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, 10,123, 10, 9,111,117,116,118, 97,108,117, +101, 32, 61, 32, 49, 46, 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, +114,103, 98, 95,105,110,118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32, +111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,118,101, 99, 51, 40, 49, 46, + 48, 41, 32, 45, 32,105,110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, 46, 97, 41, 59, 10,125, 10, 10,118,111,105, +100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32,115,116,101,110, 99, +105,108, 44, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111, +117,116,115,116,101,110, 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,110,116,101,110,115,105,116, +121, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110,116,101,110,115,105,116,121, 59, 10, 9,111, +117,116,105,110,116,101,110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105,116,121, 42,115,116,101,110, 99,105,108, 59, + 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10, +118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32,115,116,101,110, + 99,105,108, 44, 32,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,116,101,110, + 99,105,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, + 97, 99,116, 32, 61, 32,114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 46, +114,103, 98, 44, 32,114,103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, + 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,109, 97, +112,112,105,110,103, 95,111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,111,102,115, 44, 32, +111,117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, 99,111, 32, 61, + 32,116,101,120, 99,111, 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,109, 97,112,112,105, +110,103, 95,115,105,122,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,115,105,122,101, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, 99,111, 32, 61, 32, +115,105,122,101, 42,116,101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 50,100, 95,109, 97,112,112, +105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, + 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120,121, 42, 48, 46, 53, 32, 43, 32,118,101, 99, + 50, 40, 48, 46, 53, 44, 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, +120, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, + 97, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, +111,114, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101, +120, 99,111, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, +116,101,120, 95,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, + 32,105,109, 97, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 47, 32, 84,104,101, + 32,105,110,118,101,114,116, 32,111,102, 32,116,104,101, 32,114,101,100, 32, 99,104, 97,110,110,101,108, 32,105,115, 32,116,111, + 32,109, 97,107,101, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,109, 97,112, 32, 99,111,109,112,108,105, 97, +110,116, 32,119,105,116,104, 32,116,104,101, 32,111,117,116,115,105,100,101, 32,119,111,114,108,100, 46, 10, 9, 47, 47, 32, 73, +116, 32,110,101,101,100,115, 32,116,111, 32, 98,101, 32,100,111,110,101, 32, 98,101, 99, 97,117,115,101, 32,105,110, 32, 66,108, +101,110,100,101,114, 10, 9, 47, 47, 32,116,104,101, 32,110,111,114,109, 97,108, 32,117,115,101,100, 32,112,111,105,110,116,115, + 32,105,110,119, 97,114,100, 46, 10, 9, 47, 47, 32, 83,104,111,117,108,100, 32,116,104,105,115, 32,101,118,101,114, 32, 99,104, + 97,110,103,101, 32,116,104,105,115, 32,110,101,103, 97,116,101, 32,109,117,115,116, 32, 98,101, 32,114,101,109,111,118,101,100, + 46, 10, 32, 32, 32, 32,118,101, 99, 52, 32, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, + 44, 32,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 50, 46, 48, 42, 40,118,101, 99, 51, + 40, 45, 99,111,108,111,114, 46,114, 44, 32, 99,111,108,111,114, 46,103, 44, 32, 99,111,108,111,114, 46, 98, 41, 32, 45, 32,118, +101, 99, 51, 40, 45, 48, 46, 53, 44, 32, 48, 46, 53, 44, 32, 48, 46, 53, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116, +101,120, 95, 98,117,109,112, 95,110,111,114,109, 97,108,115, 95,105,110,105,116, 40, 32,118,101, 99, 51, 32,118, 78, 44, 32,111, +117,116, 32,118,101, 99, 51, 32,118, 78,111,114,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 44, 32,111, +117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 32, 41, 10,123, 10, 9,118, 78,111, +114,103, 32, 61, 32,118, 78, 59, 10, 9,118, 78, 97, 99, 99, 32, 61, 32,118, 78, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110, +105,116,117,100,101, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10, 47, 42, 42, 32,104,101,108,112,101,114, 32,109,101,116,104,111, +100, 32,116,111, 32,101,120,116,114, 97, 99,116, 32,116,104,101, 32,117,112,112,101,114, 32,108,101,102,116, 32, 51,120, 51, 32, +109, 97,116,114,105,120, 32,102,114,111,109, 32, 97, 32, 52,120, 52, 32,109, 97,116,114,105,120, 32, 42, 47, 10,109, 97,116, 51, + 32,116,111, 95,109, 97,116, 51, 40,109, 97,116, 52, 32,109, 52, 41, 10,123, 10, 9,109, 97,116, 51, 32,109, 51, 59, 10, 9,109, + 51, 91, 48, 93, 32, 61, 32,109, 52, 91, 48, 93, 46,120,121,122, 59, 10, 9,109, 51, 91, 49, 93, 32, 61, 32,109, 52, 91, 49, 93, + 46,120,121,122, 59, 10, 9,109, 51, 91, 50, 93, 32, 61, 32,109, 52, 91, 50, 93, 46,120,121,122, 59, 10, 9,114,101,116,117,114, +110, 32,109, 51, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95,111, 98,106, +115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95, +110,111,114,109, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,109, 97,116, 52, 32,109, 86,105,101,119, 44, 32,109, 97,116, 52, 32, +109, 86,105,101,119, 73,110,118, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 44, 32,109, 97,116, 52, 32,109, 79, 98,106, 73,110, +118, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100, +101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117, +116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117,116, 32, +118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, + 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +102, 68,101,116, 32, 41, 32, 10,123, 10, 9,109, 97,116, 51, 32,111, 98,106, 50,118,105,101,119, 32, 61, 32,116,111, 95,109, 97, +116, 51, 40,109, 86,105,101,119, 32, 42, 32,109, 79, 98,106, 41, 59, 10, 9,109, 97,116, 51, 32,118,105,101,119, 50,111, 98,106, + 32, 61, 32,116,111, 95,109, 97,116, 51, 40,109, 79, 98,106, 73,110,118, 32, 42, 32,109, 86,105,101,119, 73,110,118, 41, 59, 10, + 9, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,118,105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100, +120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,118, +105,101,119, 50,111, 98,106, 32, 42, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, + 51, 32,118, 78, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,115,117,114,102, 95,110,111,114,109, 32, 42, 32,111, 98, +106, 50,118,105,101,119, 32, 41, 59, 10, 10, 9,118, 82, 49, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, + 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, + 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100,111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, + 32, 41, 59, 10, 9, 10, 9, 47, 42, 32,112,114,101,116,114, 97,110,115,102,111,114,109, 32,118, 78, 97, 99, 99, 32, 40,105,110, + 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 41, 32,117,115,105,110,103, 32,116,104,101, 32,105,110,118,101, +114,115,101, 32,116,114, 97,110,115,112,111,115,101,100, 32, 42, 47, 10, 9,118, 82, 49, 32, 61, 32,118, 82, 49, 32, 42, 32,118, +105,101,119, 50,111, 98,106, 59, 10, 9,118, 82, 50, 32, 61, 32,118, 82, 50, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, + 9,118, 78, 32, 61, 32,118, 78, 32, 42, 32,118,105,101,119, 50,111, 98,106, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, + 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 32, 42, 32,108,101,110,103,116,104, 40,118, 78, + 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103, +110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80, +114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, + 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95,116,101,120,116,117,114,101,115,112, 97, + 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115,117,114,102, 95,110,111,114, +109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117, +100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, +111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 44, 32,111,117, +116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 9, 32, 32,111,117,116, + 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 83, 32, 61, 32,100, 70,100, +120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, 84, 32, 61, 32,100, + 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, 32, 61, 32,115,117,114,102, + 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, 97,108,105,122,101,100, 32,105,110,116,101,114,112,111,108, 97,116,101, +100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, 32, 61, 32,110,111,114,109, + 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 32, 41, 59, 10, 9, +118, 82, 50, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32, 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103, +109, 97, 83, 32, 41, 32, 41, 59, 10, 9,102, 68,101,116, 32, 61, 32,115,105,103,110, 40, 32,100,111,116, 40,118, 83,105,103,109, + 97, 83, 44, 32,118, 82, 49, 41, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, 97,103,110,105,116,117,100,101, 32, + 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95, +105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100, +101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95,111,117,116, 32, 61, 32,102, 77, 97, +103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,105,110,105,116, 95, +118,105,101,119,115,112, 97, 99,101, 40, 32,118,101, 99, 51, 32,115,117,114,102, 95,112,111,115, 44, 32,118,101, 99, 51, 32,115, +117,114,102, 95,110,111,114,109, 44, 32, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,102,108,111, 97,116, 32,102, 80,114,101,118, + 77, 97,103,110,105,116,117,100,101, 95,105,110, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, + 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95, +111,117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117,116, 44, 32, 10, 9, 9, 9, 9, 9, 9, + 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32, +111,117,116, 32,102,108,111, 97,116, 32,102, 68,101,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 51, 32,118, 83,105,103,109, 97, + 83, 32, 61, 32,100, 70,100,120, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 83,105,103, +109, 97, 84, 32, 61, 32,100, 70,100,121, 40, 32,115,117,114,102, 95,112,111,115, 32, 41, 59, 10, 9,118,101, 99, 51, 32,118, 78, + 32, 61, 32,115,117,114,102, 95,110,111,114,109, 59, 32, 47, 42, 32,110,111,114,109, 97,108,105,122,101,100, 32,105,110,116,101, +114,112,111,108, 97,116,101,100, 32,118,101,114,116,101,120, 32,110,111,114,109, 97,108, 32, 42, 47, 10, 9, 10, 9,118, 82, 49, + 32, 61, 32, 99,114,111,115,115, 40, 32,118, 83,105,103,109, 97, 84, 44, 32,118, 78, 32, 41, 59, 10, 9,118, 82, 50, 32, 61, 32, + 99,114,111,115,115, 40, 32,118, 78, 44, 32,118, 83,105,103,109, 97, 83, 32, 41, 32, 59, 10, 9,102, 68,101,116, 32, 61, 32,100, +111,116, 32, 40, 32,118, 83,105,103,109, 97, 83, 44, 32,118, 82, 49, 32, 41, 59, 10, 9, 10, 9,102,108,111, 97,116, 32,102, 77, + 97,103,110,105,116,117,100,101, 32, 61, 32, 97, 98,115, 40,102, 68,101,116, 41, 59, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, + 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 42, 32, 40,102, 77, 97,103,110,105,116,117,100,101, 32, 47, 32,102, 80,114,101, +118, 77, 97,103,110,105,116,117,100,101, 95,105,110, 41, 59, 10, 9,102, 80,114,101,118, 77, 97,103,110,105,116,117,100,101, 95, +111,117,116, 32, 61, 32,102, 77, 97,103,110,105,116,117,100,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98, +117,109,112, 95,116, 97,112, 51, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, +105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97, +116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 83, 84,108,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, + 59, 10, 9,118,101, 99, 50, 32, 83, 84,108,114, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32,100, 70,100,120, 40,116, +101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, + 32, 43, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 32, 59, 10, 9, 10, 9,102,108,111, 97,116, 32, 72,108,108, + 44, 72,108,114, 44, 72,117,108, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, + 97, 44, 32, 83, 84,108,108, 41, 44, 32, 72,108,108, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117, +114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108,114, 41, 44, 32, 72,108,114, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, + 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117,108, 41, 44, 32, 72,117,108, 32, 41, 59, 10, 9, + 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,108,114, 32, 45, 32, 72,108,108, 41, 59, 10, 9,100, + 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117,108, 32, 45, 32, 72,108,108, 41, 59, 10,125, 10, 10,118,111, +105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,116, 97,112, 53, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, + 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, + 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, + 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32, +100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, 99, 50, 32, 83, 84, 99, 32, 61, 32,116,101,120, + 99,111, 46,120,121, 59, 10, 9,118,101, 99, 50, 32, 83, 84,108, 32, 61, 32,116,101,120, 99,111, 46,120,121, 32, 45, 32, 48, 46, + 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,114, 32, 61, 32,116,101,120, 99,111, 46,120,121, + 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,120, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,100, 32, 61, 32,116,101,120, + 99,111, 46,120,121, 32, 45, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9,118,101, 99, 50, 32, 83, 84,117, 32, + 61, 32,116,101,120, 99,111, 46,120,121, 32, 43, 32, 48, 46, 53, 32, 42, 32, 84,101,120, 68,121, 32, 59, 10, 9, 10, 9,102,108, +111, 97,116, 32, 72, 99, 44, 72,108, 44, 72,114, 44, 72,100, 44, 72,117, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101, +120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84, 99, 41, 44, 32, 72, 99, 32, 41, 59, 10, 9,114,103, 98,116,111, 98, +119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,108, 41, 44, 32, 72,108, 32, 41, 59, 10, 9,114, +103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,114, 41, 44, 32, 72,114, 32, + 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,100, 41, + 44, 32, 72,100, 32, 41, 59, 10, 9,114,103, 98,116,111, 98,119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, + 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, + 72,114, 32, 45, 32, 72,108, 41, 59, 10, 9,100, 66,116, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117, 32, 45, 32, + 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95,100,101,114,105,118, 40, 32,118,101, + 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,105, +109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, + 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,116, 32, 41, 32, 10,123, 10, 9,102,108,111, 97,116, 32, +115, 32, 61, 32, 49, 46, 48, 59, 9, 9, 47, 47, 32,110,101,103, 97,116,101, 32,116,104,105,115, 32,105,102, 32,102,108,105,112, +112,101,100, 32,116,101,120,116,117,114,101, 32, 99,111,111,114,100,105,110, 97,116,101, 10, 9,118,101, 99, 50, 32, 84,101,120, + 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118,101, 99, 50, 32, 84,101,120, 68,121, + 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9, 10, 9, 47, 47, 32,116,104,105,115, 32,118, 97, +114,105, 97,110,116, 32,117,115,105,110,103, 32, 97, 32,100,101,114,105,118, 97,116,105,118,101, 32,109, 97,112, 32,105,115, 32, +100,101,115, 99,114,105, 98,101,100, 32,104,101,114,101, 10, 9, 47, 47, 32,104,116,116,112, 58, 47, 47,109,109,105,107,107,101, +108,115,101,110, 51,100, 46, 98,108,111,103,115,112,111,116, 46, 99,111,109, 47, 50, 48, 49, 49, 47, 48, 55, 47,100,101,114,105, +118, 97,116,105,118,101, 45,109, 97,112,115, 46,104,116,109,108, 10, 9,118,101, 99, 50, 32,100,105,109, 32, 61, 32,118,101, 99, + 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, 95,121, 41, 59, 10, 9,118,101, 99, 50, 32,100, 66,100,117,118, 32, 61, 32,104, + 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, 46, 48, 42,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101, +120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, 46, 48, 41, 59, 10, 9, 10, 9,100, 66,115, 32, 61, 32,100, 66,100,117,118, 46, +120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,120, 46,121, 59, 10, 9, +100, 66,116, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,121, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46, +121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112, +108,121, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,102,108,111, 97,116, + 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, 44, 32,118,101, 99, 51, 32,118, + 78, 97, 99, 99, 95,105,110, 44, 10, 9, 9, 9, 9, 9, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111, +117,116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, + 10, 9,118,101, 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, + 40, 32,100, 66,115, 32, 42, 32,118, 82, 49, 32, 43, 32,100, 66,116, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 10, 9,118, 78, + 97, 99, 99, 95,111,117,116, 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, 83,117,114,102, 71,114, 97,100, 59, 10, + 9,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,118, 78, 97, + 99, 99, 95,111,117,116, 32, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,117,109,112, 95, 97,112,112,108, +121, 95,116,101,120,115,112, 97, 99,101, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116, 32,100, 66, +115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,118, 82, 50, + 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,102,108,111, 97, +116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,121, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, + 95,105,110, 44, 10, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32,111,117,116, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,111,117, +116, 44, 32,111,117,116, 32,118,101, 99, 51, 32,112,101,114,116,117,114, 98,101,100, 95,110,111,114,109, 32, 41, 32, 10,123, 10, + 9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 9,118, +101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41, 59, 10, 10, 9,118,101, + 99, 51, 32,118, 83,117,114,102, 71,114, 97,100, 32, 61, 32,115,105,103,110, 40,102, 68,101,116, 41, 32, 42, 32, 40, 32, 10, 9, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,115, 32, 47, 32,108,101,110,103,116,104, 40, 32,118,101, 99, 50, 40,105, +109, 97, 95,120, 42, 84,101,120, 68,120, 46,120, 44, 32,105,109, 97, 95,121, 42, 84,101,120, 68,120, 46,121, 41, 32, 41, 32, 42, + 32,118, 82, 49, 32, 43, 32, 10, 9, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100, 66,116, 32, 47, 32,108,101,110,103,116, +104, 40, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 42, 84,101,120, 68,121, 46,120, 44, 32,105,109, 97, 95,121, 42, 84,101,120, + 68,121, 46,121, 41, 32, 41, 32, 42, 32,118, 82, 50, 32, 41, 59, 10, 9, 9, 9, 9, 10, 9,118, 78, 97, 99, 99, 95,111,117,116, + 32, 61, 32,118, 78, 97, 99, 99, 95,105,110, 32, 45, 32,118, 83,117,114,102, 71,114, 97,100, 59, 10, 9,112,101,114,116,117,114, + 98,101,100, 95,110,111,114,109, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 32,118, 78, 97, 99, 99, 95,111,117,116, 32, + 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,101,103, 97,116,101, 95,116,101,120,110,111,114,109, 97,108, + 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, + 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 45,110,111,114,109, 97,108, 46,120, 44, + 32, 45,110,111,114,109, 97,108, 46,121, 44, 32,110,111,114,109, 97,108, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, +116,101,120, 95,110,115,112, 97, 99,101, 95,116, 97,110,103,101,110,116, 40,118,101, 99, 52, 32,116, 97,110,103,101,110,116, 44, + 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,116,101,120,110,111,114,109, 97,108, 44, 32,111,117, +116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,118,101, 99, 51, 32, 66, 32, 61, 32,116, 97, +110,103,101,110,116, 46,119, 32, 42, 32, 99,114,111,115,115, 40,110,111,114,109, 97,108, 44, 32,116, 97,110,103,101,110,116, 46, +120,121,122, 41, 59, 10, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,116,101,120,110,111,114,109, 97,108, 46,120, 42, +116, 97,110,103,101,110,116, 46,120,121,122, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,121, 42, 66, 32, 43, 32,116,101, +120,110,111,114,109, 97,108, 46,122, 42,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110, +111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101, +120, 95, 98,108,101,110,100, 95,110,111,114,109, 97,108, 40,102,108,111, 97,116, 32,110,111,114,102, 97, 99, 44, 32,118,101, 99, + 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,110,101,119,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, + 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, 40, 49, 46, + 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42,110,111,114,109, 97,108, 32, 43, 32,110,111,114,102, 97, 99, 42,110,101,119,110, +111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117, +116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 32, 77, 65, 84, 69, 82, 73, 65, 76, 32, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95, +115,117,110, 95,104,101,109,105, 40,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32, +108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105, +115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32,108, 97,109,112,118,101, 99, 59, 10, 9,100,105,115,116, 32, 61, 32, + 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109, +112, 95,118,105,115,105, 98,105,108,105,116,121, 95,111,116,104,101,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, + 32,108, 97,109,112, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, +100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, + 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 9,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40,108,118, 41, + 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,118, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, + 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,108, +105,110,101, 97,114, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, + 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, + 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100,105,115,116, 41, 59, 10,125, 10, + 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,115,113,117, 97,114,101, 40,102,108,111, + 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, + 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115, +116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105, +100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,115,108,105,100,101,114,115, 40,102,108,111, 97,116, 32,108, 97,109, +112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,108,100, 49, 44, 32,102,108,111, 97,116, 32,108,100, 50, 44, 32,102,108,111, + 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102, +108,111, 97,116, 32,108, 97,109,112,100,105,115,116,107,119, 32, 61, 32,108, 97,109,112,100,105,115,116, 42,108, 97,109,112,100, +105,115,116, 59, 10, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100, +105,115,116, 32, 43, 32,108,100, 49, 42,100,105,115,116, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 42, 61, 32,108, 97,109, +112,100,105,115,116,107,119, 47, 40,108, 97,109,112,100,105,115,116,107,119, 32, 43, 32,108,100, 50, 42,100,105,115,116, 42,100, +105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95, 99,117,114,118,101, + 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32, 99,117,114,118,101, +109, 97,112, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, + 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,116,101,120,116,117,114,101, 50, 68, 40, 99,117,114,118,101, +109, 97,112, 44, 32,118,101, 99, 50, 40,100,105,115,116, 47,108, 97,109,112,100,105,115,116, 44, 32, 48, 46, 48, 41, 41, 46,120, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,112,104,101,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 93db8340aac..239903208ec 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -230,6 +230,20 @@ typedef struct bArmatureActuator { struct Object *subtarget; } bArmatureActuator; +typedef struct bSteeringActuator { + char pad[5]; + char flag; + short facingaxis; + int type; /* 0=seek, 1=flee, 2=path following */ + float dist; + float velocity; + float acceleration; + float turnspeed; + int updateTime; + struct Object *target; + struct Object *navmesh; +} bSteeringActuator; + typedef struct bActuator { struct bActuator *next, *prev, *mynew; short type; @@ -295,6 +309,7 @@ typedef struct bActuator { #define ACT_SHAPEACTION 21 #define ACT_STATE 22 #define ACT_ARMATURE 23 +#define ACT_STEERING 24 /* actuator flag */ #define ACT_SHOW 1 @@ -511,6 +526,16 @@ typedef struct bActuator { #define ACT_CAMERA_X (float)'x' #define ACT_CAMERA_Y (float)'y' +/* steeringactuator->type */ +#define ACT_STEERING_SEEK 0 +#define ACT_STEERING_FLEE 1 +#define ACT_STEERING_PATHFOLLOWING 2 +/* steeringactuator->flag */ +#define ACT_STEERING_SELFTERMINATED 1 +#define ACT_STEERING_ENABLEVISUALIZATION 2 +#define ACT_STEERING_AUTOMATICFACING 4 +#define ACT_STEERING_NORMALUP 8 + #endif diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index cdfcf465c6c..b721dc60e73 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -92,7 +92,8 @@ typedef struct CustomData { #define CD_ID_MCOL 21 #define CD_TEXTURE_MCOL 22 #define CD_CLOTH_ORCO 23 -#define CD_NUMTYPES 24 +#define CD_RECAST 24 +#define CD_NUMTYPES 25 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -117,6 +118,7 @@ typedef struct CustomData { #define CD_MASK_MDISPS (1 << CD_MDISPS) #define CD_MASK_WEIGHT_MCOL (1 << CD_WEIGHT_MCOL) #define CD_MASK_CLOTH_ORCO (1 << CD_CLOTH_ORCO) +#define CD_MASK_RECAST (1 << CD_RECAST) /* CustomData.flag */ diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index e3510b3a25a..61c4a660992 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -184,6 +184,10 @@ typedef struct PartialVisibility { unsigned int totface, totedge, totvert, pad; } PartialVisibility; +typedef struct MRecast{ + int i; +} MRecast; + /* mvert->flag (1=SELECT) */ #define ME_SPHERETEST 2 #define ME_VERT_TMP_TAG 4 diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 32a78cb823a..ed060d58123 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -74,6 +74,7 @@ typedef enum ModifierType { eModifierType_WeightVGEdit, eModifierType_WeightVGMix, eModifierType_WeightVGProximity, + eModifierType_NavMesh, NUM_MODIFIER_TYPES } ModifierType; @@ -749,6 +750,10 @@ typedef struct ScrewModifierData { #define MOD_SCREW_OBJECT_OFFSET (1<<2) // #define MOD_SCREW_OBJECT_ANGLE (1<<4) +typedef struct NavMeshModifierData { + ModifierData modifier; +} NavMeshModifierData; + typedef struct WarpModifierData { ModifierData modifier; @@ -818,7 +823,7 @@ typedef struct WeightVGEditModifierData { int mask_tex_mapping; char mask_tex_uvlayer_name[32]; /* Name of the UV layer. */ - /* Padding… */ + /* Padding... */ int pad_i1; } WeightVGEditModifierData; @@ -863,7 +868,7 @@ typedef struct WeightVGMixModifierData { int mask_tex_mapping; /* How to map the texture! */ char mask_tex_uvlayer_name[32]; /* Name of the UV layer. */ - /* Padding… */ + /* Padding... */ int pad_i1; } WeightVGMixModifierData; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 820b244ca6c..a2150292193 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -191,6 +191,8 @@ typedef struct Object { float max_vel; /* clamp the maximum velocity 0.0 is disabled */ float min_vel; /* clamp the maximum velocity 0.0 is disabled */ float m_contactProcessingThreshold; + float obstacleRad; + char pad0[4]; short rotmode; /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */ @@ -475,6 +477,8 @@ typedef struct DupliObject { #define OB_SOFT_BODY 0x20000 #define OB_OCCLUDER 0x40000 #define OB_SENSOR 0x80000 +#define OB_NAVMESH 0x100000 +#define OB_HASOBSTACLE 0x200000 /* ob->gameflag2 */ #define OB_NEVER_DO_ACTIVITY_CULLING 1 @@ -495,6 +499,7 @@ typedef struct DupliObject { #define OB_BODY_TYPE_SOFT 4 #define OB_BODY_TYPE_OCCLUDER 5 #define OB_BODY_TYPE_SENSOR 6 +#define OB_BODY_TYPE_NAVMESH 7 /* ob->scavisflag */ #define OB_VIS_SENS 1 diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index c44f10efde8..af19aa490ae 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -51,6 +51,8 @@ typedef struct TreeStore { #define TSE_CLOSED 1 #define TSE_SELECTED 2 #define TSE_TEXTBUT 4 +#define TSE_CHILDSEARCH 8 +#define TSE_SEARCHMATCH 16 /* TreeStoreElem types in BIF_outliner.h */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index bc50c710d76..66244e87995 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -426,8 +426,38 @@ typedef struct GameFraming { #define SCE_GAMEFRAMING_EXTEND 1 #define SCE_GAMEFRAMING_SCALE 2 +typedef struct RecastData +{ + float cellsize; + float cellheight; + float agentmaxslope; + float agentmaxclimb; + float agentheight; + float agentradius; + float edgemaxlen; + float edgemaxerror; + float regionminsize; + float regionmergesize; + int vertsperpoly; + float detailsampledist; + float detailsamplemaxerror; +} RecastData; + typedef struct GameData { + /* standalone player */ + struct GameFraming framing; + short fullscreen, xplay, yplay, freqplay; + short depth, attrib, rt1, rt2; + + /* stereo/dome mode */ + struct GameDome dome; + short stereoflag, stereomode; + short pad2, pad3; + float eyeseparation, pad1; + RecastData recastData; + + /* physics (it was in world)*/ float gravity; /*Gravitation constant for the game world*/ @@ -440,21 +470,12 @@ typedef struct GameData { * bit 3: (gameengine): Activity culling is enabled. * bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling */ - short mode, flag, matmode, pad[3]; + short mode, flag, matmode, pad[2]; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; short ticrate, maxlogicstep, physubstep, maxphystep; - - /* standalone player */ - struct GameFraming framing; - short fullscreen, xplay, yplay, freqplay; - short depth, attrib, rt1, rt2; - - /* stereo/dome mode */ - struct GameDome dome; - short stereoflag, stereomode; - short pad2, pad3; - float eyeseparation, pad1; + short obstacleSimulation; + float levelHeight; } GameData; #define STEREO_NOSTEREO 1 @@ -478,6 +499,11 @@ typedef struct GameData { #define WOPHY_ODE 4 #define WOPHY_BULLET 5 +/* obstacleSimulation */ +#define OBSTSIMULATION_NONE 0 +#define OBSTSIMULATION_TOI_rays 1 +#define OBSTSIMULATION_TOI_cells 2 + /* GameData.flag */ #define GAME_RESTRICT_ANIM_UPDATES (1 << 0) #define GAME_ENABLE_ALL_FRAMES (1 << 1) @@ -494,6 +520,7 @@ typedef struct GameData { #define GAME_IGNORE_DEPRECATION_WARNINGS (1 << 12) #define GAME_ENABLE_ANIMATION_RECORD (1 << 13) #define GAME_SHOW_MOUSE (1 << 14) +#define GAME_SHOW_OBSTACLE_SIMULATION (1 << 15) #define GAME_GLSL_NO_COLOR_MANAGEMENT (1 << 15) /* Note: GameData.flag is a short (max 16 flags). To add more flags, GameData.flag needs to be an int */ diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 588e8458de1..3ec26cdadb4 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -238,6 +238,8 @@ typedef struct SpeedControlVars { int lastValidFrame; } SpeedControlVars; +#define MAXSEQ 32 + #define SELECT 1 /* Editor->over_flag */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 66b10bcbf21..1627d4d2acb 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -861,6 +861,7 @@ enum { /* outliner search flags (SpaceOops->search_flags) */ #define SO_FIND_CASE_SENSITIVE (1<<0) #define SO_FIND_COMPLETE (1<<1) +#define SO_SEARCH_RECURSIVE (1<<2) /* headerbuttons: 450-499 */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 43dc532d4f6..d3ac09dc812 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -607,6 +607,12 @@ extern UserDef U; /* from blenkernel blender.c */ /* zoom is up/down if this flag is set (otherwise forward/backward) */ #define NDOF_ZOOM_UPDOWN (1 << 7) #define NDOF_ZOOM_INVERT (1 << 8) +#define NDOF_ROTATE_INVERT_AXIS (1 << 9) +#define NDOF_TILT_INVERT_AXIS (1 << 10) +#define NDOF_ROLL_INVERT_AXIS (1 << 11) +#define NDOF_PANX_INVERT_AXIS (1 << 12) +#define NDOF_PANY_INVERT_AXIS (1 << 13) +#define NDOF_PANZ_INVERT_AXIS (1 << 14) #ifdef __cplusplus diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 5da125bb440..8af4fe7b76b 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -974,7 +974,15 @@ int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *re short RNA_type_to_ID_code(StructRNA *type); StructRNA *ID_code_to_RNA_type(short idcode); -void RNA_warning(const char *format, ...) + +/* macro which inserts the function name */ +#ifdef __GNUC__ +# define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args) +#else /* MSVC doesnt support variable length args in macros */ +# define RNA_warning _RNA_warning +#endif + +void _RNA_warning(const char *format, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 1, 2))) #endif diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index e7d0c5cdec2..1ccd6d9a1d7 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -5374,7 +5374,8 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i return 0; } -void RNA_warning(const char *format, ...) +/* use RNA_warning macro which includes __func__ suffix */ +void _RNA_warning(const char *format, ...) { va_list args; @@ -5382,6 +5383,11 @@ void RNA_warning(const char *format, ...) vprintf(format, args); va_end(args); + /* gcc macro adds '\n', but cant use for other compilers */ +#ifndef __GNUC__ + fputc('\n', stdout); +#endif + #ifdef WITH_PYTHON { extern void PyC_LineSpit(void); diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 3d0e177c94e..7356af05dcb 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -60,6 +60,7 @@ EnumPropertyItem actuator_type_items[] ={ {ACT_SOUND, "SOUND", 0, "Sound", ""}, {ACT_STATE, "STATE", 0, "State", ""}, {ACT_VISIBILITY, "VISIBILITY", 0, "Visibility", ""}, + {ACT_STEERING, "STEERING", 0, "Steering", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME @@ -103,6 +104,8 @@ static StructRNA* rna_Actuator_refine(struct PointerRNA *ptr) return &RNA_StateActuator; case ACT_ARMATURE: return &RNA_ArmatureActuator; + case ACT_STEERING: + return &RNA_SteeringActuator; default: return &RNA_Actuator; } @@ -435,6 +438,7 @@ EnumPropertyItem *rna_Actuator_type_itemf(bContext *C, PointerRNA *ptr, Property RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_PROPERTY); RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_RANDOM); RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_SCENE); + RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_STEERING); RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_SOUND); RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_STATE); @@ -480,6 +484,18 @@ static void rna_Actuator_Armature_update(Main *bmain, Scene *scene, PointerRNA * constraint[0] = 0; } +static void rna_SteeringActuator_navmesh_set(PointerRNA *ptr, PointerRNA value) +{ + bActuator *act = (bActuator*)ptr->data; + bSteeringActuator *sa = (bSteeringActuator*) act->data; + + Object* obj = value.data; + if (obj && obj->body_type==OB_BODY_TYPE_NAVMESH) + sa->navmesh = obj; + else + sa->navmesh = NULL; +} + /* note: the following set functions exists only to avoid id refcounting */ static void rna_Actuator_editobject_mesh_set(PointerRNA *ptr, PointerRNA value) { @@ -1900,6 +1916,108 @@ static void rna_def_armature_actuator(BlenderRNA *brna) RNA_def_property_update(prop, NC_LOGIC, NULL); } +static void rna_def_steering_actuator(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem prop_type_items[] ={ + {ACT_STEERING_SEEK, "SEEK", 0, "Seek", ""}, + {ACT_STEERING_FLEE, "FLEE", 0, "Flee", ""}, + {ACT_STEERING_PATHFOLLOWING, "PATHFOLLOWING", 0, "Path following", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem facingaxis_items[] ={ + {1, "X", 0, "X", ""}, + {2, "Y", 0, "Y", ""}, + {3, "Z", 0, "Z", ""}, + {4, "-X", 0, "-X", ""}, + {5, "-Y", 0, "-Y", ""}, + {6, "-Z", 0, "-Z", ""}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "SteeringActuator", "Actuator"); + RNA_def_struct_ui_text(srna, "Steering Actuator", ""); + RNA_def_struct_sdna_from(srna, "bSteeringActuator", "data"); + + prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, prop_type_items); + RNA_def_property_ui_text(prop, "Behavior", ""); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "velocity"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Velocity", "Velocity magnitude"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "acceleration", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "acceleration"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Acceleration", "Max acceleration"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "turn_speed", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "turnspeed"); + RNA_def_property_range(prop, 0.0, 720.0); + RNA_def_property_ui_text(prop, "Turn Speed", "Max turn speed"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "dist"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Dist", "Relax distance"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_pointer_sdna(prop, NULL, "target"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Target Object", "Set target object"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "self_terminated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_SELFTERMINATED); + RNA_def_property_ui_text(prop, "Self Terminated", "Terminate when target is reached"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "show_visualization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_ENABLEVISUALIZATION); + RNA_def_property_ui_text(prop, "Visualize", "Enable debug visualization"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "update_period", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "updateTime"); + RNA_def_property_ui_range(prop, -1, 100000, 1, 1); + RNA_def_property_ui_text(prop, "Update period", "Path update period"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "navmesh", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_pointer_sdna(prop, NULL, "navmesh"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Navigation Mesh Object", "Navigation mesh"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_SteeringActuator_navmesh_set", NULL, NULL); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "facing", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_AUTOMATICFACING); + RNA_def_property_ui_text(prop, "Facing", "Enable automatic facing"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "facing_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "facingaxis"); + RNA_def_property_enum_items(prop, facingaxis_items); + RNA_def_property_ui_text(prop, "Axis", "Axis for automatic facing"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop= RNA_def_property(srna, "normal_up", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_NORMALUP); + RNA_def_property_ui_text(prop, "N", "Use normal of the navmesh to set \"UP\" vector"); + RNA_def_property_update(prop, NC_LOGIC, NULL); +} + void RNA_def_actuator(BlenderRNA *brna) { rna_def_actuator(brna); @@ -1921,6 +2039,7 @@ void RNA_def_actuator(BlenderRNA *brna) rna_def_shape_action_actuator(brna); rna_def_state_actuator(brna); rna_def_armature_actuator(brna); + rna_def_steering_actuator(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 2e8e8520dbf..464f676b7f6 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -68,6 +68,7 @@ EnumPropertyItem modifier_type_items[] ={ {eModifierType_Screw, "SCREW", ICON_MOD_SCREW, "Screw", ""}, {eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""}, {eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""}, + {0, "", 0, "Modify", ""}, {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""}, {eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""}, {eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""}, @@ -90,6 +91,7 @@ EnumPropertyItem modifier_type_items[] ={ {eModifierType_Collision, "COLLISION", ICON_MOD_PHYSICS, "Collision", ""}, {eModifierType_Explode, "EXPLODE", ICON_MOD_EXPLODE, "Explode", ""}, {eModifierType_Fluidsim, "FLUID_SIMULATION", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""}, + {eModifierType_NavMesh, "NAVMESH", ICON_MOD_PHYSICS, "Navigation mesh", ""}, {eModifierType_ParticleInstance, "PARTICLE_INSTANCE", ICON_MOD_PARTICLES, "Particle Instance", ""}, {eModifierType_ParticleSystem, "PARTICLE_SYSTEM", ICON_MOD_PARTICLES, "Particle System", ""}, {eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""}, @@ -187,6 +189,8 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr) return &RNA_ScrewModifier; case eModifierType_Warp: return &RNA_WarpModifier; + case eModifierType_NavMesh: + return &RNA_NavMeshModifier; case eModifierType_WeightVGEdit: return &RNA_VertexWeightEditModifier; case eModifierType_WeightVGMix: @@ -2486,6 +2490,17 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update");*/ } +static void rna_def_modifier_navmesh(BlenderRNA *brna) +{ + StructRNA *srna; + /* PropertyRNA *prop; */ /* UNUSED */ + + srna= RNA_def_struct(brna, "NavMeshModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "NavMesh Modifier", "NavMesh modifier"); + RNA_def_struct_sdna(srna, "NavMeshModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_DECIM); +} + static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna) { static EnumPropertyItem weightvg_mask_tex_map_items[] = { @@ -2510,7 +2525,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna) prop= RNA_def_property(srna, "mask_constant", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); - RNA_def_property_ui_range(prop, -1.0, 1.0, 10, 0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 0); RNA_def_property_ui_text(prop, "Influence", "Global influence of current modifications on vgroup."); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -2707,9 +2722,9 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem proximity_geometry_items[] = { - {MOD_WVG_PROXIMITY_GEOM_VERTS, "VERTEX", ICON_VERTEXSEL, "Vertex", ""}, - {MOD_WVG_PROXIMITY_GEOM_EDGES, "EDGE", ICON_EDGESEL, "Edge", ""}, - {MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", ""}, + {MOD_WVG_PROXIMITY_GEOM_VERTS, "VERTEX", ICON_VERTEXSEL, "Vertex", "Compute distance to nearest vertex."}, + {MOD_WVG_PROXIMITY_GEOM_EDGES, "EDGE", ICON_EDGESEL, "Edge", "Compute distance to nearest edge."}, + {MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", "Compute distance to nearest face."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem weightvg_proximity_falloff_type_items[] = { @@ -2748,7 +2763,9 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "proximity_flags"); RNA_def_property_enum_items(prop, proximity_geometry_items); RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */ - RNA_def_property_ui_text(prop, "Proximity Geometry", "Use shortest distance to target object's geometry as weight"); + RNA_def_property_ui_text(prop, "Proximity Geometry", + "Use the shortest computed distance to target object's geometry " + "as weight."); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE); @@ -2760,13 +2777,13 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna) prop= RNA_def_property(srna, "min_dist", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_range(prop, 0.0, 1000.0, 10, 0); - RNA_def_property_ui_text(prop, "Lowest Dist", "Distance mapping to weight 0.0."); + RNA_def_property_ui_text(prop, "Lowest Dist", "Distance mapping to weight 0.0 (or weight 1.0 if above Highest Dist)."); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "max_dist", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_range(prop, 0.0, 1000.0, 10, 0); - RNA_def_property_ui_text(prop, "Highest Dist", "Distance mapping to weight 1.0."); + RNA_def_property_ui_text(prop, "Highest Dist", "Distance mapping to weight 1.0 (or weight 0.0 if below Lowest Dist)."); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE); @@ -2875,6 +2892,7 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_smoke(brna); rna_def_modifier_solidify(brna); rna_def_modifier_screw(brna); + rna_def_modifier_navmesh(brna); rna_def_modifier_weightvgedit(brna); rna_def_modifier_weightvgmix(brna); rna_def_modifier_weightvgproximity(brna); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 49a0458977a..0554e4d00ad 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -922,7 +922,7 @@ static void def_whileloop(StructRNA *srna) prop = RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); - RNA_def_property_range(prop, 0.0f, 10000000.0f); + RNA_def_property_range(prop, 0.0f, SHRT_MAX); RNA_def_property_ui_text(prop, "Max. Iterations", "Limit for number of iterations"); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeGroup_update"); } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 829c5aaa78e..7d037264609 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -868,6 +868,8 @@ static int rna_GameObjectSettings_physics_type_get(PointerRNA *ptr) if (!(ob->gameflag & OB_COLLISION)) { if (ob->gameflag & OB_OCCLUDER) { ob->body_type = OB_BODY_TYPE_OCCLUDER; + } else if (ob->gameflag & OB_NAVMESH){ + ob->body_type = OB_BODY_TYPE_NAVMESH; } else { ob->body_type = OB_BODY_TYPE_NO_COLLISION; } @@ -897,31 +899,35 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value) switch (ob->body_type) { case OB_BODY_TYPE_SENSOR: ob->gameflag |= OB_SENSOR|OB_COLLISION|OB_GHOST; - ob->gameflag &= ~(OB_OCCLUDER|OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_ACTOR|OB_ANISOTROPIC_FRICTION|OB_DO_FH|OB_ROT_FH|OB_COLLISION_RESPONSE); + ob->gameflag &= ~(OB_OCCLUDER|OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_ACTOR|OB_ANISOTROPIC_FRICTION|OB_DO_FH|OB_ROT_FH|OB_COLLISION_RESPONSE|OB_NAVMESH); break; case OB_BODY_TYPE_OCCLUDER: ob->gameflag |= OB_OCCLUDER; - ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_DYNAMIC); + ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_DYNAMIC|OB_NAVMESH); + break; + case OB_BODY_TYPE_NAVMESH: + ob->gameflag |= OB_NAVMESH; + ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_DYNAMIC|OB_OCCLUDER); break; case OB_BODY_TYPE_NO_COLLISION: - ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC); + ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC|OB_NAVMESH); break; case OB_BODY_TYPE_STATIC: ob->gameflag |= OB_COLLISION; - ob->gameflag &= ~(OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR); + ob->gameflag &= ~(OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR|OB_NAVMESH); break; case OB_BODY_TYPE_DYNAMIC: ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_ACTOR; - ob->gameflag &= ~(OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR); + ob->gameflag &= ~(OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR|OB_NAVMESH); break; case OB_BODY_TYPE_RIGID: ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_RIGID_BODY|OB_ACTOR; - ob->gameflag &= ~(OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR); + ob->gameflag &= ~(OB_SOFT_BODY|OB_OCCLUDER|OB_SENSOR|OB_NAVMESH); break; default: case OB_BODY_TYPE_SOFT: ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_SOFT_BODY|OB_ACTOR; - ob->gameflag &= ~(OB_RIGID_BODY|OB_OCCLUDER|OB_SENSOR); + ob->gameflag &= ~(OB_RIGID_BODY|OB_OCCLUDER|OB_SENSOR|OB_NAVMESH); /* assume triangle mesh, if no bounds chosen for soft body */ if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype<OB_BOUND_POLYH)) @@ -1358,6 +1364,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna) {OB_BODY_TYPE_SOFT, "SOFT_BODY", 0, "Soft Body", "Soft body"}, {OB_BODY_TYPE_OCCLUDER, "OCCLUDE", 0, "Occlude", "Occluder for optimizing scene rendering"}, {OB_BODY_TYPE_SENSOR, "SENSOR", 0, "Sensor", "Collision Sensor, detects static and dynamic objects but not the other collision sensor objects"}, + {OB_BODY_TYPE_NAVMESH, "NAVMESH", 0, "Navigation Mesh", "Navigation mesh"}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "GameObjectSettings", NULL); @@ -1527,6 +1534,15 @@ static void rna_def_object_game_settings(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "bsoft"); RNA_def_property_ui_text(prop, "Soft Body Settings", "Settings for Bullet soft body simulation"); + prop= RNA_def_property(srna, "create_obstacle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "gameflag", OB_HASOBSTACLE); + RNA_def_property_ui_text(prop, "Create obstacle", "Create representation for obstacle simulation"); + + prop= RNA_def_property(srna, "obstacle_radius", PROP_FLOAT, PROP_NONE|PROP_UNIT_LENGTH); + RNA_def_property_float_sdna(prop, NULL, "obstacleRad"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Obstacle Radius", "Radius of object representation in obstacle simulation"); + /* state */ prop= RNA_def_property(srna, "states_visible", PROP_BOOLEAN, PROP_LAYER_MEMBER); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ed4a5e641b2..7718651a767 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -39,6 +39,7 @@ #include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "BLI_math.h" /* Include for Bake Options */ #include "RE_pipeline.h" @@ -1677,6 +1678,96 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) else RNA_def_property_clear_flag(prop, PROP_EDITABLE); } +static void rna_def_scene_game_recast_data(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "SceneGameRecastData", NULL); + RNA_def_struct_sdna(srna, "RecastData"); + RNA_def_struct_nested(brna, srna, "Scene"); + RNA_def_struct_ui_text(srna, "Recast Data", "Recast data for a Game datablock"); + + prop= RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "cellsize"); + RNA_def_property_ui_range(prop, 0.1, 1, 1, 2); + RNA_def_property_ui_text(prop, "Cell Size", "Rasterized cell size"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "cell_height", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "cellheight"); + RNA_def_property_ui_range(prop, 0.1, 1, 1, 2); + RNA_def_property_ui_text(prop, "Cell Height", "Rasterized cell height"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "agent_height", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "agentheight"); + RNA_def_property_ui_range(prop, 0.1, 5, 1, 2); + RNA_def_property_ui_text(prop, "Agent Height", "Minimum height where the agent can still walk"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "agent_radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "agentradius"); + RNA_def_property_ui_range(prop, 0.1, 5, 1, 2); + RNA_def_property_ui_text(prop, "Agent Radius", "Radius of the agent"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "max_climb", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "agentmaxclimb"); + RNA_def_property_ui_range(prop, 0.1, 5, 1, 2); + RNA_def_property_ui_text(prop, "Max Climb", "Maximum height between grid cells the agent can climb"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "max_slope", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "agentmaxslope"); + RNA_def_property_range(prop, 0, M_PI/2); + RNA_def_property_ui_text(prop, "Max Slope", "Maximum walkable slope angle in degrees"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + + prop= RNA_def_property(srna, "region_min_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "regionminsize"); + RNA_def_property_ui_range(prop, 0, 150, 1, 2); + RNA_def_property_ui_text(prop, "Min Region Size", "Minimum regions size. Smaller regions will be deleted"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "region_merge_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "regionmergesize"); + RNA_def_property_ui_range(prop, 0, 150, 1, 2); + RNA_def_property_ui_text(prop, "Merged Region Size", "Minimum regions size. Smaller regions will be merged"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "edge_max_len", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "edgemaxlen"); + RNA_def_property_ui_range(prop, 0, 50, 1, 2); + RNA_def_property_ui_text(prop, "Max Edge Length", "Maximum contour edge length"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "edge_max_error", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "edgemaxerror"); + RNA_def_property_ui_range(prop, 0.1, 3.0, 1, 2); + RNA_def_property_ui_text(prop, "Max Edge Error", "Maximum distance error from contour to cells"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "verts_per_poly", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "vertsperpoly"); + RNA_def_property_ui_range(prop, 3, 12, 1, 0); + RNA_def_property_ui_text(prop, "Verts Per Poly", "Max number of vertices per polygon"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "sample_dist", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "detailsampledist"); + RNA_def_property_ui_range(prop, 0.0, 16.0, 1, 2); + RNA_def_property_ui_text(prop, "Sample Distance", "Detail mesh sample spacing"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "sample_max_error", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "detailsamplemaxerror"); + RNA_def_property_ui_range(prop, 0.0, 16.0, 1, 2); + RNA_def_property_ui_text(prop, "Max Sample Error", "Detail mesh simplification max sample error"); + RNA_def_property_update(prop, NC_SCENE, NULL); +} + static void rna_def_scene_game_data(BlenderRNA *brna) { StructRNA *srna; @@ -1726,6 +1817,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna) {GAME_MAT_GLSL, "GLSL", 0, "GLSL", "OpenGL shading language shaders"}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem obstacle_simulation_items[] = { + {OBSTSIMULATION_NONE, "NONE", 0, "None", ""}, + {OBSTSIMULATION_TOI_rays, "RVO (rays)", 0, "RVO (rays)", ""}, + {OBSTSIMULATION_TOI_cells, "RVO (cells)", 0, "RVO (cells)", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "SceneGameData", NULL); RNA_def_struct_sdna(srna, "GameData"); RNA_def_struct_nested(brna, srna, "Scene"); @@ -1978,6 +2075,33 @@ static void rna_def_scene_game_data(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_GLSL_NO_EXTRA_TEX); RNA_def_property_ui_text(prop, "GLSL Extra Textures", "Use extra textures like normal or specular maps for GLSL rendering"); RNA_def_property_update(prop, NC_SCENE|NA_EDITED, "rna_Scene_glsl_update"); + + /* obstacle simulation */ + prop= RNA_def_property(srna, "obstacle_simulation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "obstacleSimulation"); + RNA_def_property_enum_items(prop, obstacle_simulation_items); + RNA_def_property_ui_text(prop, "Obstacle simulation", "Simulation used for obstacle avoidance in the game engine"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "level_height", PROP_FLOAT, PROP_ACCELERATION); + RNA_def_property_float_sdna(prop, NULL, "levelHeight"); + RNA_def_property_range(prop, 0.0f, 200.0f); + RNA_def_property_ui_text(prop, "Level height", "Max difference in heights of obstacles to enable their interaction"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "show_obstacle_simulation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_OBSTACLE_SIMULATION); + RNA_def_property_ui_text(prop, "Visualization", "Enable debug visualization for obstacle simulation"); + + /* Recast Settings */ + prop= RNA_def_property(srna, "recast_data", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "recastData"); + RNA_def_property_struct_type(prop, "SceneGameRecastData"); + RNA_def_property_ui_text(prop, "Recast Data", ""); + + /* Nestled Data */ + rna_def_scene_game_recast_data(brna); } static void rna_def_scene_render_layer(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 249cdb28ae1..3463b2f6c03 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -43,6 +43,7 @@ #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_space_types.h" +#include "DNA_sequence_types.h" #include "DNA_view3d_types.h" #include "WM_api.h" @@ -1758,7 +1759,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna) prop= RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "chanshown"); RNA_def_property_ui_text(prop, "Display Channel", "The channel number shown in the image preview. 0 is the result of all strips combined"); - RNA_def_property_range(prop, -5, 32); // MAXSEQ --- todo, move from BKE_sequencer.h, allow up to 5 layers up the metastack. Should be dynamic... + RNA_def_property_range(prop, -5, MAXSEQ); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "draw_overexposed", PROP_INT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index d4ac9880290..92c93f41dfc 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -46,7 +46,7 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, int flag= 0; if(!prop) { - RNA_warning("rna_uiItemR: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7d0502f1be9..4bc828cdc4f 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1959,6 +1959,7 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + static float default_dir[3] = {0.f, 1.f, 0.f}; srna= RNA_def_struct(brna, "UserSolidLight", NULL); RNA_def_struct_sdna(srna, "SolidLight"); @@ -1972,6 +1973,7 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna) prop= RNA_def_property(srna, "direction", PROP_FLOAT, PROP_DIRECTION); RNA_def_property_float_sdna(prop, NULL, "vec"); RNA_def_property_array(prop, 3); + RNA_def_property_float_array_default(prop, default_dir); RNA_def_property_ui_text(prop, "Direction", "The direction that the OpenGL light is shining"); RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update"); @@ -2791,6 +2793,36 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Invert Axes", "Toggle between moving the viewpoint or moving the scene being viewed"); /* in 3Dx docs, this is called 'object mode' vs. 'target camera mode' */ + /* 3D view: roll */ + prop= RNA_def_property(srna, "ndof_roll_invert_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROLL_INVERT_AXIS); + RNA_def_property_ui_text(prop, "Invert roll Axis", "Invert roll axis"); + + /* 3D view: tilt */ + prop= RNA_def_property(srna, "ndof_tilt_invert_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_TILT_INVERT_AXIS); + RNA_def_property_ui_text(prop, "Invert tilt Axis", "Invert tilt axis"); + + /* 3D view: rotate */ + prop= RNA_def_property(srna, "ndof_rotate_invert_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTATE_INVERT_AXIS); + RNA_def_property_ui_text(prop, "Invert rotation Axis", "Invert rotation axis"); + + /* 3D view: pan x */ + prop= RNA_def_property(srna, "ndof_panx_invert_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANX_INVERT_AXIS); + RNA_def_property_ui_text(prop, "Invert x Axis", "Invert x axis"); + + /* 3D view: pan y */ + prop= RNA_def_property(srna, "ndof_pany_invert_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANY_INVERT_AXIS); + RNA_def_property_ui_text(prop, "Invert y Axis", "Invert y axis"); + + /* 3D view: pan z */ + prop= RNA_def_property(srna, "ndof_panz_invert_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANZ_INVERT_AXIS); + RNA_def_property_ui_text(prop, "Invert z Axis", "Invert z axis"); + /* 3D view: fly */ prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON); diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index f374de3fd17..d8344a9e19b 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -40,6 +40,7 @@ set(INC set(INC_SYS ${ZLIB_INCLUDE_DIRS} + ${GLEW_INCLUDE_PATH} ) set(SRC @@ -64,6 +65,7 @@ set(SRC intern/MOD_meshdeform.c intern/MOD_mirror.c intern/MOD_multires.c + intern/MOD_navmesh.cpp intern/MOD_none.c intern/MOD_particleinstance.c intern/MOD_particlesystem.c @@ -114,4 +116,13 @@ if(NOT WITH_MOD_FLUID) add_definitions(-DDISABLE_ELBEEM) endif() +if(WITH_GAMEENGINE) + # for MOD_navmesh.cpp + add_definitions(-DWITH_GAMEENGINE) + list(APPEND INC + ../gpu + ../../../extern/recastnavigation/Recast/Include + ) +endif() + blender_add_lib(bf_modifiers "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 0ba906a433b..0ae9768c0e6 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -72,6 +72,7 @@ extern ModifierTypeInfo modifierType_ShapeKey; extern ModifierTypeInfo modifierType_Solidify; extern ModifierTypeInfo modifierType_Screw; extern ModifierTypeInfo modifierType_Warp; +extern ModifierTypeInfo modifierType_NavMesh; extern ModifierTypeInfo modifierType_WeightVGEdit; extern ModifierTypeInfo modifierType_WeightVGMix; extern ModifierTypeInfo modifierType_WeightVGProximity; diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index 66dd00f0248..da37539e950 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -1,12 +1,13 @@ #!/usr/bin/python Import ('env') -sources = env.Glob('intern/*.c') +sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') incs = '. ./intern' -incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern' +incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern #/extern/glew/include' incs += ' ../render/extern/include ../blenloader' incs += ' ../include ../blenlib ../makesdna ../makesrna ../blenkernel ../blenkernel/intern' +incs += ' ../gpu' incs += ' ' + env['BF_ZLIB_INC'] @@ -19,6 +20,10 @@ defs += ['WITH_MOD_DECIMATE'] if env['BF_NO_ELBEEM']: defs.append('DISABLE_ELBEEM') +if env['WITH_BF_GAMEENGINE']: + incs += ' #/extern/recastnavigation/Recast/Include' + defs.append('WITH_GAMEENGINE') + env.BlenderLib ( libname = 'bf_modifiers', sources = sources, includes = Split(incs), defines=defs, libtype=['core','player'], priority = [80, 40] ) diff --git a/source/blender/modifiers/intern/MOD_navmesh.cpp b/source/blender/modifiers/intern/MOD_navmesh.cpp new file mode 100644 index 00000000000..927085033fc --- /dev/null +++ b/source/blender/modifiers/intern/MOD_navmesh.cpp @@ -0,0 +1,300 @@ +/* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2005 by the Blender Foundation. +* All rights reserved. +* +* Contributor(s): +* +* ***** END GPL LICENSE BLOCK ***** +* +*/ +#include <math.h> + +#ifdef WITH_GAMEENGINE +# include "Recast.h" +#endif + +extern "C"{ + +#ifdef WITH_GAMEENGINE +# include "BKE_navmesh_conversion.h" +# include "GL/glew.h" +# include "GPU_buffers.h" +# include "GPU_draw.h" +#endif + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" +#include "BKE_customdata.h" +#include "MEM_guardedalloc.h" + +inline int bit(int a, int b) +{ + return (a & (1 << b)) >> b; +} + +inline void intToCol(int i, float* col) +{ + int r = bit(i, 0) + bit(i, 3) * 2 + 1; + int g = bit(i, 1) + bit(i, 4) * 2 + 1; + int b = bit(i, 2) + bit(i, 5) * 2 + 1; + col[0] = 1 - r*63.0f/255.0f; + col[1] = 1 - g*63.0f/255.0f; + col[2] = 1 - b*63.0f/255.0f; +} + + +static void initData(ModifierData *md) +{ + /* NavMeshModifierData *nmmd = (NavMeshModifierData*) md; */ /* UNUSED */ +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + /* NavMeshModifierData *nmmd = (NavMeshModifierData*) md; */ + /* NavMeshModifierData *tnmmd = (NavMeshModifierData*) target; */ + + //.todo - deep copy +} + +/* +static void (*drawFacesSolid_original)(DerivedMesh *dm, float (*partial_redraw_planes)[4], + int fast, int (*setMaterial)(int, void *attribs)) = NULL;*/ + +#ifdef WITH_GAMEENGINE + +static void drawNavMeshColored(DerivedMesh *dm) +{ + int a, glmode; + MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT); + MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE); + int* polygonIdx = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); + if (!polygonIdx) + return; + const float BLACK_COLOR[3] = {0.f, 0.f, 0.f}; + float col[3]; + /* + //UI_ThemeColor(TH_WIRE); + glDisable(GL_LIGHTING); + glLineWidth(2.0); + dm->drawEdges(dm, 0, 1); + glLineWidth(1.0); + glEnable(GL_LIGHTING);*/ + + glDisable(GL_LIGHTING); + if(GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. drawNavMeshColored\n" ); + //glShadeModel(GL_SMOOTH); + glBegin(glmode = GL_QUADS); + for(a = 0; a < dm->numFaceData; a++, mface++) { + int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; + int polygonIdx = *(int*)CustomData_get(&dm->faceData, a, CD_RECAST); + if (polygonIdx<=0) + memcpy(col, BLACK_COLOR, 3*sizeof(float)); + else + intToCol(polygonIdx, col); + + if(new_glmode != glmode) { + glEnd(); + glBegin(glmode = new_glmode); + } + glColor3fv(col); + glVertex3fv(mvert[mface->v1].co); + glVertex3fv(mvert[mface->v2].co); + glVertex3fv(mvert[mface->v3].co); + if(mface->v4) { + glVertex3fv(mvert[mface->v4].co); + } + } + glEnd(); + } + glEnable(GL_LIGHTING); +} + +static void navDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) +{ + drawNavMeshColored(dm); +} + +static void navDM_drawFacesSolid(DerivedMesh *dm, + float (*partial_redraw_planes)[4], + int fast, int (*setMaterial)(int, void *attribs)) +{ + //drawFacesSolid_original(dm, partial_redraw_planes, fast, setMaterial); + drawNavMeshColored(dm); +} +#endif /* WITH_GAMEENGINE */ + +static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,DerivedMesh *dm) +{ +#ifdef WITH_GAMEENGINE + DerivedMesh *result; + int maxFaces = dm->getNumFaces(dm); + + result = CDDM_copy(dm); + if (!CustomData_has_layer(&result->faceData, CD_RECAST)) + { + int *sourceRecastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); + CustomData_add_layer_named(&result->faceData, CD_RECAST, CD_DUPLICATE, + sourceRecastData, maxFaces, "recastData"); + } + int *recastData = (int*)CustomData_get_layer(&result->faceData, CD_RECAST); + result->drawFacesTex = navDM_drawFacesTex; + result->drawFacesSolid = navDM_drawFacesSolid; + + + //process mesh + int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0; + float* verts=NULL; + unsigned short *dtris=NULL, *dmeshes=NULL, *polys=NULL; + int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL; + + bool res = buildNavMeshDataByDerivedMesh(dm, vertsPerPoly, nverts, verts, ndtris, dtris, + npolys, dmeshes, polys, dtrisToPolysMap, dtrisToTrisMap, + trisToFacesMap); + if (res) + { + //invalidate concave polygon + for (size_t polyIdx=0; polyIdx<(size_t)npolys; polyIdx++) + { + unsigned short* poly = &polys[polyIdx*2*vertsPerPoly]; + if (!polyIsConvex(poly, vertsPerPoly, verts)) + { + //set negative polygon idx to all faces + unsigned short *dmesh = &dmeshes[4*polyIdx]; + unsigned short tbase = dmesh[2]; + unsigned short tnum = dmesh[3]; + for (unsigned short ti=0; ti<tnum; ti++) + { + unsigned short triidx = dtrisToTrisMap[tbase+ti]; + unsigned short faceidx = trisToFacesMap[triidx]; + if (recastData[faceidx]>0) + recastData[faceidx] = -recastData[faceidx]; + } + } + } + + } + else + { + printf("Error during creation polygon infos\n"); + } + + //clean up + if (verts!=NULL) + delete verts; + if (dtris!=NULL) + delete dtris; + if (dmeshes!=NULL) + delete dmeshes; + if (polys!=NULL) + delete polys; + if (dtrisToPolysMap!=NULL) + delete dtrisToPolysMap; + if (dtrisToTrisMap!=NULL) + delete dtrisToTrisMap; + if (trisToFacesMap!=NULL) + delete trisToFacesMap; + + return result; +#else // WITH_GAMEENGINE + return dm; +#endif // WITH_GAMEENGINE +} + +/* +static int isDisabled(ModifierData *md, int useRenderParams) +{ + NavMeshModifierData *amd = (NavMeshModifierData*) md; + return false; +}*/ + + + +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, + int useRenderParams, int isFinalCalc) +{ + DerivedMesh *result = NULL; + NavMeshModifierData *nmmd = (NavMeshModifierData*) md; + bool hasRecastData = CustomData_has_layer(&derivedData->faceData, CD_RECAST)>0; + if (ob->body_type!=OB_BODY_TYPE_NAVMESH || !hasRecastData ) + { + //convert to nav mesh object: + //1)set physics type + ob->gameflag &= ~OB_COLLISION; + ob->gameflag |= OB_NAVMESH; + ob->body_type = OB_BODY_TYPE_NAVMESH; + //2)add and init recast data layer + if (!hasRecastData) + { + Mesh* obmesh = (Mesh *)ob->data; + if (obmesh) + { + int numFaces = obmesh->totface; + CustomData_add_layer_named(&obmesh->fdata, CD_RECAST, CD_CALLOC, NULL, numFaces, "recastData"); + int* recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_RECAST); + for (int i=0; i<numFaces; i++) + { + recastData[i] = i+1; + } + CustomData_add_layer_named(&derivedData->faceData, CD_RECAST, CD_REFERENCE, recastData, numFaces, "recastData"); + } + } + } + + result = createNavMeshForVisualization(nmmd, derivedData); + + return result; +} + + +ModifierTypeInfo modifierType_NavMesh = { + /* name */ "NavMesh", + /* structName */ "NavMeshModifierData", + /* structSize */ sizeof(NavMeshModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ (ModifierTypeFlag) (eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_Single), + /* copyData */ copyData, + /* deformVerts */ 0, + /* deformMatrices */ 0, + /* deformVertsEM */ 0, + /* deformMatricesEM */ 0, + /* applyModifier */ applyModifier, + /* applyModifierEM */ 0, + /* initData */ initData, + /* requiredDataMask */ 0, + /* freeData */ 0, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; + +}; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 26e9d48cd0a..a2fe947a523 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -295,6 +295,7 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(Solidify); INIT_TYPE(Screw); INIT_TYPE(Warp); + INIT_TYPE(NavMesh); INIT_TYPE(WeightVGEdit); INIT_TYPE(WeightVGMix); INIT_TYPE(WeightVGProximity); diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 51465cc80b0..98615c70553 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -135,7 +135,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne MappingInfoModifierData t_map; float (*v_co)[3]; - /* Use new generic get_texture_coords, but do not modify our DNA struct for it… + /* Use new generic get_texture_coords, but do not modify our DNA struct for it... * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ? * What e.g. if a modifier wants to use several textures ? * Why use only v_co, and not MVert (or both) ? diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h index 00c63a3d5d5..ce3520f1900 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.h +++ b/source/blender/modifiers/intern/MOD_weightvg_util.h @@ -44,7 +44,7 @@ struct Tex; /* * XXX I'd like to make modified weights visible in WeightPaint mode, - * but couldn't figure a way to do this… + * but couldn't figure a way to do this... * Maybe this will need changes in mesh_calc_modifiers (DerivedMesh.c)? * Or the WeightPaint mode code itself? */ @@ -53,7 +53,7 @@ struct Tex; * Util functions. * **************************************/ -/* We cannot divide by zero (what a surprise…). +/* We cannot divide by zero (what a surprise...). * So if -MOD_WEIGHTVGROUP_DIVMODE_ZEROFLOOR < weightf < MOD_WEIGHTVGROUP_DIVMODE_ZEROFLOOR, * we clamp weightf to this value (or its negative version). * Also used to avoid null power factor. diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 0b6b69b2b3c..fb6d4dc10e6 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -28,7 +28,7 @@ /* * XXX I'd like to make modified weights visible in WeightPaint mode, - * but couldn't figure a way to do this… + * but couldn't figure a way to do this... * Maybe this will need changes in mesh_calc_modifiers (DerivedMesh.c)? * Or the WeightPaint mode code itself? */ @@ -211,13 +211,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der if (defgrp_idx < 0) return dm; - /* XXX All this to avoid copying dm when not needed… However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file… + /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute + * time! See scene 5 of the WeighVG test file... */ #if 0 /* Get actual dverts (ie vertex group data). */ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data… */ + /* If no dverts, return unmodified data... */ if (dvert == NULL) return dm; @@ -231,7 +231,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess… + * I'm missing something here, I guess... */ // DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ ret = CDDM_copy(dm); diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 8bfc56fc18f..f1422a342eb 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -28,7 +28,7 @@ /* * XXX I'd like to make modified weights visible in WeightPaint mode, - * but couldn't figure a way to do this… + * but couldn't figure a way to do this... * Maybe this will need changes in mesh_calc_modifiers (DerivedMesh.c)? * Or the WeightPaint mode code itself? */ @@ -62,7 +62,7 @@ static float mix_weight(float weight, float weight2, char mix_mode) #if 0 /* * XXX Don't know why, but the switch version takes many CPU time, - * and produces lag in realtime playback… + * and produces lag in realtime playback... */ switch (mix_mode) { @@ -258,13 +258,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der return dm; } - /* XXX All this to avoid copying dm when not needed… However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file… + /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute + * time! See scene 5 of the WeighVG test file... */ #if 0 /* Get actual dverts (ie vertex group data). */ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data… */ + /* If no dverts, return unmodified data... */ if (dvert == NULL) return dm; @@ -278,7 +278,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess… + * I'm missing something here, I guess... */ // DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ ret = CDDM_copy(dm); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index ffb783f8adc..2daa3f797c3 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -28,7 +28,7 @@ /* * XXX I'd like to make modified weights visible in WeightPaint mode, - * but couldn't figure a way to do this… + * but couldn't figure a way to do this... * Maybe this will need changes in mesh_calc_modifiers (DerivedMesh.c)? * Or the WeightPaint mode code itself? */ @@ -63,16 +63,6 @@ #define OUT_OF_MEMORY() ((void)printf("WeightVGProximity: Out of memory.\n")) /** - * Returns the squared distance between two given points. - */ -static float squared_dist(const float *a, const float *b) -{ - float tmp[3]; - VECSUB(tmp, a, b); - return INPR(tmp, tmp); -} - -/** * Find nearest vertex and/or edge and/or face, for each vertex (adapted from shrinkwrap.c). */ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], @@ -126,7 +116,7 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], float tmp_co[3]; /* Convert the vertex to tree coordinates. */ - VECCOPY(tmp_co, v_cos[i]); + copy_v3_v3(tmp_co, v_cos[i]); space_transform_apply(loc2trgt, tmp_co); /* Use local proximity heuristics (to reduce the nearest search). @@ -137,19 +127,19 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], * This will lead in prunning of the search tree. */ if (dist_v) { - nearest_v.dist = nearest_v.index != -1 ? squared_dist(tmp_co, nearest_v.co) : FLT_MAX; + nearest_v.dist = nearest_v.index != -1 ? len_squared_v3v3(tmp_co, nearest_v.co) : FLT_MAX; /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */ BLI_bvhtree_find_nearest(treeData_v.tree, tmp_co, &nearest_v, treeData_v.nearest_callback, &treeData_v); dist_v[i] = sqrtf(nearest_v.dist); } if (dist_e) { - nearest_e.dist = nearest_e.index != -1 ? squared_dist(tmp_co, nearest_e.co) : FLT_MAX; + nearest_e.dist = nearest_e.index != -1 ? len_squared_v3v3(tmp_co, nearest_e.co) : FLT_MAX; /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */ BLI_bvhtree_find_nearest(treeData_e.tree, tmp_co, &nearest_e, treeData_e.nearest_callback, &treeData_e); dist_e[i] = sqrtf(nearest_e.dist); } if (dist_f) { - nearest_f.dist = nearest_f.index != -1 ? squared_dist(tmp_co, nearest_f.co) : FLT_MAX; + nearest_f.dist = nearest_f.index != -1 ? len_squared_v3v3(tmp_co, nearest_f.co) : FLT_MAX; /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */ BLI_bvhtree_find_nearest(treeData_f.tree, tmp_co, &nearest_f, treeData_f.nearest_callback, &treeData_f); dist_f[i] = sqrtf(nearest_f.dist); @@ -199,10 +189,24 @@ void do_map(float *weights, const int nidx, const float min_d, const float max_d { const float range_inv= 1.0f / (max_d - min_d); /* invert since multiplication is faster */ unsigned int i= nidx; - while (i-- > 0) { - if (weights[i] >= max_d) weights[i]= 1.0f; /* most likely case first */ - else if(weights[i] <= min_d) weights[i]= 0.0f; - else weights[i]= (weights[i] - min_d) * range_inv; + if(max_d == min_d) { + while (i-- > 0) { + weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */ + } + } + else if(max_d > min_d) { + while (i-- > 0) { + if (weights[i] >= max_d) weights[i]= 1.0f; /* most likely case first */ + else if(weights[i] <= min_d) weights[i]= 0.0f; + else weights[i]= (weights[i] - min_d) * range_inv; + } + } + else { + while (i-- > 0) { + if (weights[i] <= max_d) weights[i]= 1.0f; /* most likely case first */ + else if(weights[i] >= min_d) weights[i]= 0.0f; + else weights[i]= (weights[i] - min_d) * range_inv; + } } if(!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) { @@ -371,13 +375,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der if (defgrp_idx < 0) return dm; - /* XXX All this to avoid copying dm when not needed… However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file… + /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute + * time! See scene 5 of the WeighVG test file... */ #if 0 /* Get actual dverts (ie vertex group data). */ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data… */ + /* If no dverts, return unmodified data... */ if (dvert == NULL) return dm; @@ -391,7 +395,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess… + * I'm missing something here, I guess... */ // DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ ret = CDDM_copy(dm); @@ -481,6 +485,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der new_w[i] = dists_e ? minf(dists_e[i], new_w[i]) : new_w[i]; new_w[i] = dists_f ? minf(dists_f[i], new_w[i]) : new_w[i]; } + if(dists_v) MEM_freeN(dists_v); + if(dists_e) MEM_freeN(dists_e); + if(dists_f) MEM_freeN(dists_f); } /* Else, fall back to default obj2vert behavior. */ else { @@ -492,14 +499,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der } } + /* Map distances to weights. */ + do_map(new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); + /* Do masking. */ weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); - /* Map distances to weights. */ - do_map(org_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); - /* Update vgroup. Note we never add nor remove vertices from vgroup here. */ weightvg_update_vg(dvert, defgrp_idx, numIdx, indices, org_w, 0, 0.0f, 0, 0.0f); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 4fc5e23e26a..01e46ed3df9 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -341,15 +341,15 @@ static void *exec_composite_node(void *nodeexec_v) } /* return total of executable nodes, for timecursor */ -static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) +static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd) { + bNodeTree *ntree = exec->nodetree; bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeExec *nodeexec; bNode *node; bNodeSocket *sock; - int totnode= 0, group_edit= 0; - - /* note; do not add a dependency sort here, the stack was created already */ + int n, totnode= 0, group_edit= 0; /* if we are in group edit, viewer nodes get skipped when group has viewer */ for(node= ntree->nodes.first; node; node= node->next) @@ -357,10 +357,12 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER)) group_edit= 1; - for(node= ntree->nodes.first; node; node= node->next) { + /* NB: using the exec data list here to have valid dependency sort */ + for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { int a; + node = nodeexec->node; - node_get_stack(node, thd->stack, nsin, nsout); + node_get_stack(node, exec->stack, nsin, nsout); /* test the outputs */ /* skip value-only nodes (should be in type!) */ @@ -422,10 +424,11 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) /* last step: set the stack values for only-value nodes */ /* just does all now, compared to a full buffer exec this is nothing */ if(totnode) { - for(node= ntree->nodes.first; node; node= node->next) { + for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; if(node->need_exec==0 && node_only_value(node)) { if(node->typeinfo->execfunc) { - node_get_stack(node, thd->stack, nsin, nsout); + node_get_stack(node, exec->stack, nsin, nsout); node->typeinfo->execfunc(thd->rd, node, nsin, nsout); } } @@ -436,14 +439,17 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) } /* while executing tree, free buffers from nodes that are not needed anymore */ -static void freeExecutableNode(bNodeTree *ntree, bNodeTreeExec *exec) +static void freeExecutableNode(bNodeTreeExec *exec) { /* node outputs can be freed when: - not a render result or image node - when node outputs go to nodes all being set NODE_FINISHED */ + bNodeTree *ntree = exec->nodetree; + bNodeExec *nodeexec; bNode *node; bNodeSocket *sock; + int n; /* set exec flag for finished nodes that might need freed */ for(node= ntree->nodes.first; node; node= node->next) { @@ -451,8 +457,11 @@ static void freeExecutableNode(bNodeTree *ntree, bNodeTreeExec *exec) if(node->exec & NODE_FINISHED) node->exec |= NODE_FREEBUFS; } - /* clear this flag for input links that are not done yet */ - for(node= ntree->nodes.first; node; node= node->next) { + /* clear this flag for input links that are not done yet. + * Using the exec data for valid dependency sort. + */ + for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; if((node->exec & NODE_FINISHED)==0) { for(sock= node->inputs.first; sock; sock= sock->next) if(sock->link) @@ -526,7 +535,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) ListBase threads; ThreadData thdata; int totnode, curnode, rendering= 1, n; - bNodeTreeExec *exec= NULL; + bNodeTreeExec *exec= ntree->execdata; if(ntree==NULL) return; @@ -551,7 +560,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) BLI_srandom(rd->cfra); /* sets need_exec tags in nodes */ - curnode = totnode= setExecutableNodes(ntree, &thdata); + curnode = totnode= setExecutableNodes(exec, &thdata); BLI_init_threads(&threads, exec_composite_node, rd->threads); @@ -597,7 +606,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) /* freeing unused buffers */ if(rd->scemode & R_COMP_FREE) - freeExecutableNode(ntree, exec); + freeExecutableNode(exec); } } else rendering= 1; diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 07f3eb943cc..d7830b6a260 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -878,7 +878,7 @@ static void loop_sync(bNodeTree *ntree, int sync_in_out) while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC))) sync = sync->next; - if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) { + if (sync && !(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) { if (sock->storage==NULL) { /* if mirror index is 0, the sockets is newly added and a new mirror must be created. */ mirror = node_group_expose_socket(ntree, sock, sync_in_out); diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 642e4be10d7..28f0f983454 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -107,8 +107,7 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat) { bNodeTreeExec *exec; - if(!ntree->execdata) - exec = ntreeShaderBeginExecTree(ntree, 1); + exec = ntreeShaderBeginExecTree(ntree, 1); ntreeExecGPUNodes(exec, mat, 1); @@ -211,7 +210,7 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) memset(shr, 0, sizeof(ShadeResult)); if (!exec) - exec = ntree->execdata = ntreeShaderBeginExecTree(exec->nodetree, 1); + exec = ntree->execdata = ntreeShaderBeginExecTree(ntree, 1); nts= ntreeGetThreadStack(exec, shi->thread); ntreeExecThreadNodes(exec, nts, &scd, shi->thread); diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c index 585d1e59d15..ddb8c42a730 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geom.c +++ b/source/blender/nodes/shader/nodes/node_shader_geom.c @@ -72,12 +72,12 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **UNUSED(i } /* out: global, local, view, orco, uv, normal, vertex color */ - VECCOPY(out[GEOM_OUT_GLOB]->vec, shi->gl); - VECCOPY(out[GEOM_OUT_LOCAL]->vec, shi->co); - VECCOPY(out[GEOM_OUT_VIEW]->vec, shi->view); - VECCOPY(out[GEOM_OUT_ORCO]->vec, shi->lo); - VECCOPY(out[GEOM_OUT_UV]->vec, suv->uv); - VECCOPY(out[GEOM_OUT_NORMAL]->vec, shi->vno); + copy_v3_v3(out[GEOM_OUT_GLOB]->vec, shi->gl); + copy_v3_v3(out[GEOM_OUT_LOCAL]->vec, shi->co); + copy_v3_v3(out[GEOM_OUT_VIEW]->vec, shi->view); + copy_v3_v3(out[GEOM_OUT_ORCO]->vec, shi->lo); + copy_v3_v3(out[GEOM_OUT_UV]->vec, suv->uv); + copy_v3_v3(out[GEOM_OUT_NORMAL]->vec, shi->vno); if (shi->totcol) { /* find vertex color layer by name */ diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 984bfed3ff9..21fb4db115b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -120,13 +120,11 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, normalize_v3(shi->vn); } else - VECCOPY(shi->vn, shi->vno); + copy_v3_v3(shi->vn, shi->vno); /* custom option to flip normal */ if(node->custom1 & SH_NODE_MAT_NEG) { - shi->vn[0]= -shi->vn[0]; - shi->vn[1]= -shi->vn[1]; - shi->vn[2]= -shi->vn[2]; + negate_v3(shi->vn); } if (node->type == SH_NODE_MATERIAL_EXT) { diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index dec0de4a6ab..9d7928c4432 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -5,7 +5,7 @@ Import ('env') incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes' -incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager' +incs += ' ../imbuf ../blenloader ../gpu ../render/extern/include ../windowmanager' incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include' incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC'] diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index b7e67ec5a93..a1571dc028c 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -209,6 +209,10 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) } /* returns the exception string as a new PyUnicode object, depends on external traceback module */ +#if 0 + +/* this version uses traceback module but somehow fails on UI errors */ + PyObject *PyC_ExceptionBuffer(void) { PyObject *traceback_mod= NULL; @@ -236,6 +240,78 @@ error_cleanup: return ret; } +#else /* verbose, non-threadsafe version */ +PyObject *PyC_ExceptionBuffer(void) +{ + PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */ + PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */ + PyObject *string_io = NULL; + PyObject *string_io_buf = NULL; + PyObject *string_io_mod= NULL; + PyObject *string_io_getvalue= NULL; + + PyObject *error_type, *error_value, *error_traceback; + + if (!PyErr_Occurred()) + return NULL; + + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + PyErr_Clear(); + + /* import io + * string_io = io.StringIO() + */ + + if(! (string_io_mod= PyImport_ImportModule("io")) ) { + goto error_cleanup; + } + else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) { + goto error_cleanup; + } + else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) { + goto error_cleanup; + } + + Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced. + Py_INCREF(stderr_backup); + + PySys_SetObject("stdout", string_io); // both of these are free'd when restoring + PySys_SetObject("stderr", string_io); + + PyErr_Restore(error_type, error_value, error_traceback); + PyErr_Print(); /* print the error */ + PyErr_Clear(); + + string_io_buf = PyObject_CallObject(string_io_getvalue, NULL); + + PySys_SetObject("stdout", stdout_backup); + PySys_SetObject("stderr", stderr_backup); + + Py_DECREF(stdout_backup); /* now sys owns the ref again */ + Py_DECREF(stderr_backup); + + Py_DECREF(string_io_mod); + Py_DECREF(string_io_getvalue); + Py_DECREF(string_io); /* free the original reference */ + + PyErr_Clear(); + return string_io_buf; + + +error_cleanup: + /* could not import the module so print the error and close */ + Py_XDECREF(string_io_mod); + Py_XDECREF(string_io); + + PyErr_Restore(error_type, error_value, error_traceback); + PyErr_Print(); /* print the error */ + PyErr_Clear(); + + return NULL; +} +#endif + /* string conversion, escape non-unicode chars, coerce must be set to NULL */ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 93a4b3ec269..9ed08591eea 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -32,6 +32,7 @@ set(INC ../../makesdna ../../makesrna ../../windowmanager + ../../gpu ../../../../intern/guardedalloc ) @@ -40,6 +41,7 @@ set(INC_SYS ) set(SRC + gpu.c bpy.c bpy_app.c bpy_app_handlers.c @@ -58,6 +60,7 @@ set(SRC bpy_util.c stubs.c + gpu.h bpy.h bpy_app.h bpy_app_handlers.h diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index e5e90380d61..e5bfc1d633f 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -40,6 +40,7 @@ #include "RNA_types.h" #include "bpy.h" +#include "gpu.h" #include "bpy_rna.h" #include "bpy_util.h" #include "bpy_traceback.h" @@ -181,6 +182,7 @@ static struct _inittab bpy_internal_modules[]= { #ifdef WITH_AUDASPACE {(char *)"aud", AUD_initPython}, #endif + {(char *)"gpu", GPU_initPython}, {NULL, NULL} }; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 2212499d842..4c382efdda3 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -5443,7 +5443,7 @@ static PyObject* pyrna_srna_ExternalType(StructRNA *srna) if(bpy_types==NULL) { PyErr_Print(); PyErr_Clear(); - fprintf(stderr, "pyrna_srna_ExternalType: failed to find 'bpy_types' module\n"); + fprintf(stderr, "%s: failed to find 'bpy_types' module\n", __func__); return NULL; } bpy_types_dict= PyModule_GetDict(bpy_types); // borrow @@ -5457,18 +5457,18 @@ static PyObject* pyrna_srna_ExternalType(StructRNA *srna) PyObject *base_compare= pyrna_srna_PyBase(srna); //PyObject *slots= PyObject_GetAttrString(newclass, "__slots__"); // cant do this because it gets superclasses values! //PyObject *bases= PyObject_GetAttrString(newclass, "__bases__"); // can do this but faster not to. - PyObject *bases= ((PyTypeObject *)newclass)->tp_bases; - PyObject *slots= PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, bpy_intern_str___slots__); + PyObject *tp_bases= ((PyTypeObject *)newclass)->tp_bases; + PyObject *tp_slots= PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, bpy_intern_str___slots__); - if(slots==NULL) { - fprintf(stderr, "pyrna_srna_ExternalType: expected class '%s' to have __slots__ defined\n\nSee bpy_types.py\n", idname); + if(tp_slots==NULL) { + fprintf(stderr, "%s: expected class '%s' to have __slots__ defined\n\nSee bpy_types.py\n", __func__, idname); newclass= NULL; } - else if(PyTuple_GET_SIZE(bases)) { - PyObject *base= PyTuple_GET_ITEM(bases, 0); + else if(PyTuple_GET_SIZE(tp_bases)) { + PyObject *base= PyTuple_GET_ITEM(tp_bases, 0); if(base_compare != base) { - fprintf(stderr, "pyrna_srna_ExternalType: incorrect subclassing of SRNA '%s'\nSee bpy_types.py\n", idname); + fprintf(stderr, "%s: incorrect subclassing of SRNA '%s'\nSee bpy_types.py\n", __func__, idname); PyC_ObSpit("Expected! ", base_compare); newclass= NULL; } @@ -5538,7 +5538,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna) } else { /* this should not happen */ - printf("Error registering '%s'\n", idname); + printf("%s: error registering '%s'\n", __func__, idname); PyErr_Print(); PyErr_Clear(); } @@ -5581,7 +5581,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) Py_DECREF(tp); /* srna owns, cant hold a ref */ } else { - fprintf(stderr, "Could not make type\n"); + fprintf(stderr, "%s: could not make type\n", __func__); pyrna= (BPy_StructRNA *) PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type); #ifdef USE_WEAKREFS pyrna->in_weakreflist= NULL; @@ -6231,10 +6231,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #endif py_class= RNA_struct_py_type_get(ptr->type); - /* rare case. can happen when registering subclasses */ if(py_class==NULL) { - fprintf(stderr, "bpy_class_call(): unable to get python class for rna struct '%.200s'\n", RNA_struct_identifier(ptr->type)); + fprintf(stderr, "%s: unable to get python class for rna struct '%.200s'\n", + __func__, RNA_struct_identifier(ptr->type)); return -1; } diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c new file mode 100644 index 00000000000..334bb1f725a --- /dev/null +++ b/source/blender/python/intern/gpu.c @@ -0,0 +1,289 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Benoit Bolsee. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/gpu.c + * \ingroup pythonintern + */ + +/* python redefines */ +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#include <Python.h> + +#include "GPU_material.h" + +#include "DNA_scene_types.h" +#include "DNA_image_types.h" +#include "DNA_material_types.h" +#include "DNA_lamp_types.h" +#include "DNA_object_types.h" +#include "DNA_ID.h" +#include "DNA_customdata_types.h" + +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + +#include "RNA_access.h" + +#include "bpy_rna.h" + +#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name) + +PyDoc_STRVAR(M_gpu_doc, + "This module provides access to the GLSL shader."); + +static struct PyModuleDef gpumodule = { + PyModuleDef_HEAD_INIT, + "gpu", /* name of module */ + M_gpu_doc, /* module documentation */ + -1, /* size of per-interpreter state of the module, + or -1 if the module keeps state in global variables. */ + NULL, NULL, NULL, NULL, NULL +}; + +PyMODINIT_FUNC +PyInit_gpu(void) +{ + PyObject* m; + + m = PyModule_Create(&gpumodule); + if(m == NULL) + return NULL; + + // device constants + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNVEC); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCO); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNIMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNPERSMAT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNENERGY); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCOL); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DBUFFER); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DIMAGE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DSHADOW); + + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1I); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1F); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_2F); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_3F); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4F); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_9F); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_16F); + PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4UB); + + PY_MODULE_ADD_CONSTANT(m, CD_MTFACE); + PY_MODULE_ADD_CONSTANT(m, CD_ORCO); + PY_MODULE_ADD_CONSTANT(m, CD_TANGENT); + PY_MODULE_ADD_CONSTANT(m, CD_MCOL); + return m; +} + +#define PY_DICT_ADD_STRING(d,s,f) \ + val = PyUnicode_FromString(s->f); \ + PyDict_SetItemString(d, #f, val); \ + Py_DECREF(val) + +#define PY_DICT_ADD_LONG(d,s,f) \ + val = PyLong_FromLong(s->f); \ + PyDict_SetItemString(d, #f, val); \ + Py_DECREF(val) + +#define PY_DICT_ADD_ID(d,s,f) \ + RNA_id_pointer_create((struct ID*)s->f, &tptr); \ + val = pyrna_struct_CreatePyObject(&tptr); \ + PyDict_SetItemString(d, #f, val); \ + Py_DECREF(val) + +#define PY_OBJ_ADD_ID(d,s,f) \ + val = PyUnicode_FromString(&s->f->id.name[2]); \ + PyObject_SetAttrString(d, #f, val); \ + Py_DECREF(val) + +#define PY_OBJ_ADD_LONG(d,s,f) \ + val = PyLong_FromLong(s->f); \ + PyObject_SetAttrString(d, #f, val); \ + Py_DECREF(val) + +#define PY_OBJ_ADD_STRING(d,s,f) \ + val = PyUnicode_FromString(s->f); \ + PyObject_SetAttrString(d, #f, val); \ + Py_DECREF(val) + +static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObject *kwds) +{ + PyObject* pyscene; + PyObject* pymat; + PyObject* as_pointer; + PyObject* pointer; + PyObject* result; + PyObject* dict; + PyObject* val; + PyObject* seq; + + int i; + Scene *scene; + PointerRNA tptr; + Material *material; + GPUShaderExport *shader; + GPUInputUniform *uniform; + GPUInputAttribute *attribute; + + static const char *kwlist[] = {"scene", "material", NULL}; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "OO:export_shader", (char**)(kwlist), &pyscene, &pymat)) + return NULL; + + if (!strcmp(Py_TYPE(pyscene)->tp_name, "Scene") && + (as_pointer = PyObject_GetAttrString(pyscene, "as_pointer")) != NULL && + PyCallable_Check(as_pointer)) { + // must be a scene object + pointer = PyObject_CallObject(as_pointer, NULL); + if (!pointer) { + PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed"); + return NULL; + } + scene = (Scene*)PyLong_AsVoidPtr(pointer); + Py_DECREF(pointer); + if (!scene) { + PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed"); + return NULL; + } + } else { + PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type"); + return NULL; + } + + if (!strcmp(Py_TYPE(pymat)->tp_name, "Material") && + (as_pointer = PyObject_GetAttrString(pymat, "as_pointer")) != NULL && + PyCallable_Check(as_pointer)) { + // must be a material object + pointer = PyObject_CallObject(as_pointer, NULL); + if (!pointer) { + PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed"); + return NULL; + } + material = (Material*)PyLong_AsVoidPtr(pointer); + Py_DECREF(pointer); + if (!material) { + PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed"); + return NULL; + } + } else { + PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type"); + return NULL; + } + // we can call our internal function at last: + shader = GPU_shader_export(scene, material); + if (!shader) { + PyErr_SetString(PyExc_RuntimeError, "cannot export shader"); + return NULL; + } + // build a dictionary + result = PyDict_New(); + if (shader->fragment) { + PY_DICT_ADD_STRING(result,shader,fragment); + } + if (shader->vertex) { + PY_DICT_ADD_STRING(result,shader,vertex); + } + seq = PyList_New(BLI_countlist(&shader->uniforms)); + for (i=0, uniform=shader->uniforms.first; uniform; uniform=uniform->next, i++) { + dict = PyDict_New(); + PY_DICT_ADD_STRING(dict,uniform,varname); + PY_DICT_ADD_LONG(dict,uniform,datatype); + PY_DICT_ADD_LONG(dict,uniform,type); + if (uniform->lamp) { + PY_DICT_ADD_ID(dict,uniform,lamp); + } + if (uniform->image) { + PY_DICT_ADD_ID(dict,uniform,image); + } + if (uniform->type == GPU_DYNAMIC_SAMPLER_2DBUFFER || + uniform->type == GPU_DYNAMIC_SAMPLER_2DIMAGE || + uniform->type == GPU_DYNAMIC_SAMPLER_2DSHADOW) { + PY_DICT_ADD_LONG(dict,uniform,texnumber); + } + if (uniform->texpixels) { + val = PyByteArray_FromStringAndSize((const char *)uniform->texpixels, uniform->texsize); + PyDict_SetItemString(dict, "texpixels", val); + Py_DECREF(val); + PY_DICT_ADD_LONG(dict,uniform,texsize); + } + PyList_SET_ITEM(seq, i, dict); + } + PyDict_SetItemString(result, "uniforms", seq); + Py_DECREF(seq); + + seq = PyList_New(BLI_countlist(&shader->attributes)); + for (i=0, attribute=shader->attributes.first; attribute; attribute=attribute->next, i++) { + dict = PyDict_New(); + PY_DICT_ADD_STRING(dict,attribute,varname); + PY_DICT_ADD_LONG(dict,attribute,datatype); + PY_DICT_ADD_LONG(dict,attribute,type); + PY_DICT_ADD_LONG(dict,attribute,number); + if (attribute->name) { + if (attribute->name[0] != 0) { + PY_DICT_ADD_STRING(dict,attribute,name); + } else { + val = PyLong_FromLong(0); + PyDict_SetItemString(dict, "name", val); + Py_DECREF(val); + } + } + PyList_SET_ITEM(seq, i, dict); + } + PyDict_SetItemString(result, "attributes", seq); + Py_DECREF(seq); + + GPU_free_shader_export(shader); + + return result; +} + +static PyMethodDef meth_export_shader[] = {{ "export_shader", (PyCFunction)GPU_export_shader, METH_VARARGS | METH_KEYWORDS, + "export_shader(scene,material)\n\n" + "Returns the GLSL shader that produces the visual effect of material in scene.\n\n" + ":return: Dictionary defining the shader, uniforms and attributes.\n" + ":rtype: Dict"}}; + +PyObject* GPU_initPython(void) +{ + PyObject* module = PyInit_gpu(); + PyModule_AddObject(module, "export_shader", (PyObject *)PyCFunction_New(meth_export_shader, NULL)); + PyDict_SetItemString(PyImport_GetModuleDict(), "gpu", module); + + return module; +} + diff --git a/source/blender/python/intern/gpu.h b/source/blender/python/intern/gpu.h new file mode 100644 index 00000000000..d604c7c6201 --- /dev/null +++ b/source/blender/python/intern/gpu.h @@ -0,0 +1,41 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This shader is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This shader is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this shader; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Benoit Bolsee. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/gpu.h + * \ingroup pythonintern + */ + +/** + * Initalizes the gpu Python module. + */ +PyObject* GPU_initPython(void); + diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 849640a5c16..e98f481b162 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -55,10 +55,10 @@ struct ImBuf; //void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); /* particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */ -int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta, const int thread); +int externtex(struct MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread); /* particle.c */ -void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype); +void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype); float texture_value_blend(float tex, float out, float fact, float facg, int blendtype); /* node_composite.c */ diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h index 0298f90c0d0..feabfea9319 100644 --- a/source/blender/render/intern/include/pixelshading.h +++ b/source/blender/render/intern/include/pixelshading.h @@ -58,10 +58,10 @@ int shadeHaloFloat(HaloRen *har, /** * Render the sky at pixel (x, y). */ -void shadeSkyPixel(float *collector, float fx, float fy, short thread); -void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread); +void shadeSkyPixel(float collector[4], float fx, float fy, short thread); +void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const float dxyview[2], short thread); void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance); -void shadeSunView(float *colf, float *view); +void shadeSunView(float col_r[3], const float view[3]); /* ------------------------------------------------------------------------- */ #endif diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 13ca40bfd20..0b339d285ce 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -338,7 +338,7 @@ typedef struct ObjectInstanceRen { struct VolumePrecache *volume_precache; - float *vectors; + float *vectors; /* (RE_WINSPEED_ELEMS * VertRen.index) */ int totvector; /* used on makeraytree */ @@ -354,8 +354,8 @@ typedef struct VertRen float co[3]; float n[3]; float *orco; - short clip; - unsigned short flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c */ + unsigned int flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c + * only an 'int' because of alignment, could be a char too */ float accum; /* accum for radio weighting, and for strand texco static particles */ int index; /* index allows extending vertren with any property */ } VertRen; diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 67c3cbcebe2..f9486b5d5c0 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -81,8 +81,8 @@ float mistfactor(float zcor, float *co); /* dist and height, return alpha */ void renderspothalo(struct ShadeInput *shi, float *col, float alpha); void add_halo_flare(Render *re); -void calc_renderco_zbuf(float *co, float *view, int z); -void calc_renderco_ortho(float *co, float x, float y, int z); +void calc_renderco_zbuf(float co[3], float *view, int z); +void calc_renderco_ortho(float co[3], float x, float y, int z); int count_mask(unsigned short mask); diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index e1fa208d0b6..06185d0ae74 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -91,7 +91,7 @@ void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); void set_normalflags(struct Render *re, struct ObjectRen *obr); -void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); +void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]); /* functions are not exported... so wrong names */ diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h index 2dca9963e4f..5bed39db3e9 100644 --- a/source/blender/render/intern/include/shadbuf.h +++ b/source/blender/render/intern/include/shadbuf.h @@ -59,13 +59,13 @@ void threaded_makeshadowbufs(struct Render *re); * @param inp The inproduct between viewvector and ? * */ -float testshadowbuf(struct Render *re, struct ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp, float mat_bias); +float testshadowbuf(struct Render *re, struct ShadBuf *shb, const float rco[3], const float dxco[3], const float dyco[3], float inp, float mat_bias); /** * Determines the shadow factor for lamp <lar>, between <p1> * and <p2>. (Which CS?) */ -float shadow_halo(LampRen *lar, float *p1, float *p2); +float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]); /** * Irregular shadowbuffer diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index 07d24ea6d66..91507ef3f98 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -63,7 +63,7 @@ void shade_volume_loop(struct ShadeInput *shi, struct ShadeResult *shr); void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip); void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from); -void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float *view, float *dxyview, float *co, float *dxco, float *dyco); +void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float *dxyview, float *co, float *dxco, float *dyco); void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z); void shade_input_set_uv(struct ShadeInput *shi); void shade_input_set_normals(struct ShadeInput *shi); @@ -96,7 +96,7 @@ void ambient_occlusion(struct ShadeInput *shi); void environment_lighting_apply(struct ShadeInput *shi, struct ShadeResult *shr); ListBase *get_lights(struct ShadeInput *shi); -float lamp_get_visibility(struct LampRen *lar, float *co, float *lv, float *dist); +float lamp_get_visibility(struct LampRen *lar, const float co[3], float *lv, float *dist); void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float *shadfac, int do_real); float fresnel_fac(float *view, float *vn, float fresnel, float fac); diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index a63c4f7f253..73f9d7a1627 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -64,11 +64,11 @@ struct ImBuf; /* texture.h */ -void do_halo_tex(struct HaloRen *har, float xn, float yn, float *colf); -void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread); +void do_halo_tex(struct HaloRen *har, float xn, float yn, float col_r[4]); +void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread); void do_material_tex(struct ShadeInput *shi); -void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf, int effect); -void do_volume_tex(struct ShadeInput *shi, float *xyz, int mapto_flag, float *col, float *val); +void do_lamp_tex(LampRen *la, const float lavec[3], struct ShadeInput *shi, float col_r[3], int effect); +void do_volume_tex(struct ShadeInput *shi, const float xyz[3], int mapto_flag, float col[3], float *val); void init_render_textures(Render *re); void end_render_textures(Render *re); @@ -77,8 +77,8 @@ void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); /* imagetexture.h */ -int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, float *texvec, float *dxt, float *dyt, struct TexResult *texres); -int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, float *texvec, struct TexResult *texres); +int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[3], const float dyt[3], struct TexResult *texres); +int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres); void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float *result); #endif /* TEXTURE_EXT_H */ diff --git a/source/blender/render/intern/include/volumetric.h b/source/blender/render/intern/include/volumetric.h index 6d8d4cbe0f2..87d74de9134 100644 --- a/source/blender/render/intern/include/volumetric.h +++ b/source/blender/render/intern/include/volumetric.h @@ -35,8 +35,8 @@ struct Isect; struct ShadeInput; struct ShadeResult; -float vol_get_density(struct ShadeInput *shi, float *co); -void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co_); +float vol_get_density(struct ShadeInput *shi, const float co[3]); +void vol_get_scattering(ShadeInput *shi, float scatter_col[3], const float co[3], const float view[3]); void shade_volume_outside(ShadeInput *shi, ShadeResult *shr); void shade_volume_inside(ShadeInput *shi, ShadeResult *shr); diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 4c87520d4d1..0d129081d62 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -51,9 +51,9 @@ void fillrect(int *rect, int x, int y, int val); * Converts a world coordinate into a homogenous coordinate in view * coordinates. */ -void projectvert(float *v1, float winmat[][4], float *adr); -void projectverto(float *v1, float winmat[][4], float *adr); -int testclip(float *v); +void projectvert(const float v1[3], float winmat[][4], float adr[4]); +void projectverto(const float v1[3], float winmat[][4], float adr[4]); +int testclip(const float v[3]); void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 2f79560efd6..c323760296b 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -142,7 +142,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, float *vec, float hasize) har= RE_findOrAddHalo(obr, obr->tothalo++); /* projectvert is done in function zbufvlaggen again, because of parts */ - VECCOPY(har->co, vec); + copy_v3_v3(har->co, vec); har->hasize= hasize; har->zd= 0.0; @@ -547,7 +547,7 @@ static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); const float *co= (&vlr->v1)[vert_index]->co; - VECCOPY(fPos, co); + copy_v3_v3(fPos, co); } static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index) @@ -576,7 +576,7 @@ static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData; VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); const float *n= (&vlr->v1)[vert_index]->n; - VECCOPY(fNorm, n); + copy_v3_v3(fNorm, n); } static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert) { @@ -585,7 +585,7 @@ static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num); float * ftang= RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, 1); if(ftang!=NULL) { - VECCOPY(&ftang[iVert*4+0], fvTangent); + copy_v3_v3(&ftang[iVert*4+0], fvTangent); ftang[iVert*4+3]=fSign; } } @@ -632,10 +632,10 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen VlakRen *vlr= RE_findOrAddVlak(obr, a); if((vlr->flag & ME_SMOOTH)==0) { - if(is_zero_v3(vlr->v1->n)) VECCOPY(vlr->v1->n, vlr->n); - if(is_zero_v3(vlr->v2->n)) VECCOPY(vlr->v2->n, vlr->n); - if(is_zero_v3(vlr->v3->n)) VECCOPY(vlr->v3->n, vlr->n); - if(vlr->v4 && is_zero_v3(vlr->v4->n)) VECCOPY(vlr->v4->n, vlr->n); + if(is_zero_v3(vlr->v1->n)) copy_v3_v3(vlr->v1->n, vlr->n); + if(is_zero_v3(vlr->v2->n)) copy_v3_v3(vlr->v2->n, vlr->n); + if(is_zero_v3(vlr->v3->n)) copy_v3_v3(vlr->v3->n, vlr->n); + if(vlr->v4 && is_zero_v3(vlr->v4->n)) copy_v3_v3(vlr->v4->n, vlr->n); } if(do_nmap_tangent) { @@ -647,17 +647,17 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen float *vtang, *ftang= RE_vlakren_get_nmap_tangent(obr, vlr, 1); vtang= find_vertex_tangent(vtangents[v1->index], tface->uv[0]); - VECCOPY(ftang, vtang); + copy_v3_v3(ftang, vtang); normalize_v3(ftang); vtang= find_vertex_tangent(vtangents[v2->index], tface->uv[1]); - VECCOPY(ftang+4, vtang); + copy_v3_v3(ftang+4, vtang); normalize_v3(ftang+4); vtang= find_vertex_tangent(vtangents[v3->index], tface->uv[2]); - VECCOPY(ftang+8, vtang); + copy_v3_v3(ftang+8, vtang); normalize_v3(ftang+8); if(v4) { vtang= find_vertex_tangent(vtangents[v4->index], tface->uv[3]); - VECCOPY(ftang+12, vtang); + copy_v3_v3(ftang+12, vtang); normalize_v3(ftang+12); } for(k=0; k<4; k++) ftang[4*k+3]=1; @@ -1023,7 +1023,7 @@ typedef struct ParticleStrandData } ParticleStrandData; /* future thread problem... */ -static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, float *vec, float *vec1) +static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, const float vec[3], const float vec1[3]) { static VertRen *v1= NULL, *v2= NULL; VlakRen *vlr= NULL; @@ -1090,27 +1090,27 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(vlr->v1->co, vec); + copy_v3_v3(vlr->v1->co, vec); add_v3_v3(vlr->v1->co, cross); - VECCOPY(vlr->v1->n, nor); + copy_v3_v3(vlr->v1->n, nor); vlr->v1->orco= sd->orco; vlr->v1->accum= -1.0f; // accum abuse for strand texco - VECCOPY(vlr->v2->co, vec); + copy_v3_v3(vlr->v2->co, vec); sub_v3_v3v3(vlr->v2->co, vlr->v2->co, cross); - VECCOPY(vlr->v2->n, nor); + copy_v3_v3(vlr->v2->n, nor); vlr->v2->orco= sd->orco; vlr->v2->accum= vlr->v1->accum; - VECCOPY(vlr->v4->co, vec1); + copy_v3_v3(vlr->v4->co, vec1); add_v3_v3(vlr->v4->co, cross); - VECCOPY(vlr->v4->n, nor); + copy_v3_v3(vlr->v4->n, nor); vlr->v4->orco= sd->orco; vlr->v4->accum= 1.0f; // accum abuse for strand texco - VECCOPY(vlr->v3->co, vec1); + copy_v3_v3(vlr->v3->co, vec1); sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross); - VECCOPY(vlr->v3->n, nor); + copy_v3_v3(vlr->v3->n, nor); vlr->v3->orco= sd->orco; vlr->v3->accum= vlr->v4->accum; @@ -1121,7 +1121,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par if(sd->surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - VECCOPY(snor, sd->surfnor); + copy_v3_v3(snor, sd->surfnor); } if(sd->uvco){ @@ -1156,23 +1156,23 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par /* first two vertices of a strand */ else if(sd->first) { if(sd->adapt){ - VECCOPY(anor, nor); - VECCOPY(avec, vec); + copy_v3_v3(anor, nor); + copy_v3_v3(avec, vec); second=1; } v1= RE_findOrAddVert(obr, obr->totvert++); v2= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(v1->co, vec); + copy_v3_v3(v1->co, vec); add_v3_v3(v1->co, cross); - VECCOPY(v1->n, nor); + copy_v3_v3(v1->n, nor); v1->orco= sd->orco; v1->accum= -1.0f; // accum abuse for strand texco - VECCOPY(v2->co, vec); + copy_v3_v3(v2->co, vec); sub_v3_v3v3(v2->co, v2->co, cross); - VECCOPY(v2->n, nor); + copy_v3_v3(v2->n, nor); v2->orco= sd->orco; v2->accum= v1->accum; } @@ -1192,8 +1192,8 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par if(sd->adapt){ second=0; - VECCOPY(anor,nor); - VECCOPY(avec,vec); + copy_v3_v3(anor,nor); + copy_v3_v3(avec,vec); } } @@ -1218,23 +1218,23 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par v1= vlr->v4; // cycle v2= vlr->v3; // cycle - VECCOPY(anor,nor); - VECCOPY(avec,vec); + copy_v3_v3(anor,nor); + copy_v3_v3(avec,vec); } else{ vlr= RE_findOrAddVlak(obr, obr->totvlak-1); } } - VECCOPY(vlr->v4->co, vec); + copy_v3_v3(vlr->v4->co, vec); add_v3_v3(vlr->v4->co, cross); - VECCOPY(vlr->v4->n, nor); + copy_v3_v3(vlr->v4->n, nor); vlr->v4->orco= sd->orco; vlr->v4->accum= -1.0f + 2.0f*sd->time; // accum abuse for strand texco - VECCOPY(vlr->v3->co, vec); + copy_v3_v3(vlr->v3->co, vec); sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross); - VECCOPY(vlr->v3->n, nor); + copy_v3_v3(vlr->v3->n, nor); vlr->v3->orco= sd->orco; vlr->v3->accum= vlr->v4->accum; @@ -1245,7 +1245,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par if(sd->surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - VECCOPY(snor, sd->surfnor); + copy_v3_v3(snor, sd->surfnor); } if(sd->uvco){ @@ -1279,7 +1279,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par } } -static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float *vec1, int first, int line) +static void static_particle_wire(ObjectRen *obr, Material *ma, const float vec[3], const float vec1[3], int first, int line) { VlakRen *vlr; static VertRen *v1; @@ -1291,13 +1291,13 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float vlr->v3= vlr->v2; vlr->v4= NULL; - VECCOPY(vlr->v1->co, vec); - VECCOPY(vlr->v2->co, vec1); + copy_v3_v3(vlr->v1->co, vec); + copy_v3_v3(vlr->v2->co, vec1); sub_v3_v3v3(vlr->n, vec, vec1); normalize_v3(vlr->n); - VECCOPY(vlr->v1->n, vlr->n); - VECCOPY(vlr->v2->n, vlr->n); + copy_v3_v3(vlr->v1->n, vlr->n); + copy_v3_v3(vlr->v2->n, vlr->n); vlr->mat= ma; vlr->ec= ME_V1V2; @@ -1305,7 +1305,7 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float } else if(first) { v1= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(v1->co, vec); + copy_v3_v3(v1->co, vec); } else { vlr= RE_findOrAddVlak(obr, obr->totvlak++); @@ -1315,11 +1315,11 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float vlr->v4= NULL; v1= vlr->v2; // cycle - VECCOPY(v1->co, vec); + copy_v3_v3(v1->co, vec); sub_v3_v3v3(vlr->n, vec, vec1); normalize_v3(vlr->n); - VECCOPY(v1->n, vlr->n); + copy_v3_v3(v1->n, vlr->n); vlr->mat= ma; vlr->ec= ME_V1V2; @@ -1376,10 +1376,10 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Particl mul_m4_v3(re->viewmat, vlr->v4->co); normal_quad_v3( vlr->n,vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - VECCOPY(vlr->v1->n,vlr->n); - VECCOPY(vlr->v2->n,vlr->n); - VECCOPY(vlr->v3->n,vlr->n); - VECCOPY(vlr->v4->n,vlr->n); + copy_v3_v3(vlr->v1->n,vlr->n); + copy_v3_v3(vlr->v2->n,vlr->n); + copy_v3_v3(vlr->v3->n,vlr->n); + copy_v3_v3(vlr->v4->n,vlr->n); vlr->mat= ma; vlr->ec= ME_V2V3; @@ -1470,7 +1470,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re { float loc[3], loc0[3], loc1[3], vel[3]; - VECCOPY(loc, state->co); + copy_v3_v3(loc, state->co); if(ren_as != PART_DRAW_BB) mul_m4_v3(re->viewmat, loc); @@ -1481,7 +1481,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re sd->time = 0.0f; sd->size = hasize; - VECCOPY(vel, state->vel); + copy_v3_v3(vel, state->vel); mul_mat3_m4_v3(re->viewmat, vel); normalize_v3(vel); @@ -1497,8 +1497,8 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re case PART_DRAW_BB: - VECCOPY(bb->vec, loc); - VECCOPY(bb->vel, state->vel); + copy_v3_v3(bb->vec, loc); + copy_v3_v3(bb->vel, state->vel); particle_billboard(re, obr, ma, bb); @@ -1892,7 +1892,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem strand= RE_findOrAddStrand(obr, obr->totstrand++); strand->buffer= strandbuf; strand->vert= svert; - VECCOPY(strand->orco, sd.orco); + copy_v3_v3(strand->orco, sd.orco); if(dosimplify) { float *ssimplify= RE_strandren_get_simplify(obr, strand, 1); @@ -1902,7 +1902,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(sd.surfnor) { float *snor= RE_strandren_get_surfnor(obr, strand, 1); - VECCOPY(snor, sd.surfnor); + copy_v3_v3(snor, sd.surfnor); } if(dosurfacecache && num >= 0) { @@ -1945,8 +1945,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem float time; if(k<=max_k){ - VECCOPY(state.co,(cache+k)->co); - VECCOPY(state.vel,(cache+k)->vel); + copy_v3_v3(state.co,(cache+k)->co); + copy_v3_v3(state.vel,(cache+k)->vel); } else continue; @@ -1955,11 +1955,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem curlen += len_v3v3((cache+k-1)->co, (cache+k)->co); time= curlen/strandlen; - VECCOPY(loc,state.co); + copy_v3_v3(loc,state.co); mul_m4_v3(re->viewmat,loc); if(strandbuf) { - VECCOPY(svert->co, loc); + copy_v3_v3(svert->co, loc); svert->strandco= -1.0f + 2.0f*time; svert++; strand->totvert++; @@ -1982,7 +1982,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(k) particle_curve(re, obr, psmd->dm, ma, &sd, loc, loc1, seed, pa_co); - VECCOPY(loc1,loc); + copy_v3_v3(loc1,loc); } } @@ -2147,7 +2147,7 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *UNUSED(me), int if(ok) { hasize= ma->hasize; - VECCOPY(vec, mvert->co); + copy_v3_v3(vec, mvert->co); mul_m4_v3(mat, vec); if(ma->mode & MA_HALOPUNO) { @@ -2161,7 +2161,7 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *UNUSED(me), int nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; normalize_v3(nor); - VECCOPY(view, vec); + copy_v3_v3(view, vec); normalize_v3(view); zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2]; @@ -2238,9 +2238,9 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve int i; /* shi->co is current render coord, just make sure at least some vector is here */ - VECCOPY(shi->co, vr->co); + copy_v3_v3(shi->co, vr->co); /* vertex normal is used for textures type 'col' and 'var' */ - VECCOPY(shi->vn, vr->n); + copy_v3_v3(shi->vn, vr->n); if(mat) mul_m4_v3(mat, shi->co); @@ -2269,7 +2269,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve /* set all rendercoords, 'texco' is an ORed value for all textures needed */ if ((texco & TEXCO_ORCO) && (vr->orco)) { - VECCOPY(shi->lo, vr->orco); + copy_v3_v3(shi->lo, vr->orco); } if (texco & TEXCO_STICKY) { float *sticky= RE_vertren_get_sticky(obr, vr, 0); @@ -2280,11 +2280,11 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve } } if (texco & TEXCO_GLOB) { - VECCOPY(shi->gl, shi->co); + copy_v3_v3(shi->gl, shi->co); mul_m4_v3(re->viewinv, shi->gl); } if (texco & TEXCO_NORM) { - VECCOPY(shi->orn, shi->vn); + copy_v3_v3(shi->orn, shi->vn); } if(texco & TEXCO_REFL) { /* not (yet?) */ @@ -2461,7 +2461,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) for(a=0; a<dl->nr; a++, data+=3, nors+=3) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, data); + copy_v3_v3(ver->co, data); mul_m4_v3(mat, ver->co); /* render normals are inverted */ @@ -2540,7 +2540,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, data= dl->verts; for (u = 0; u < sizeu; u++) { v1 = RE_findOrAddVert(obr, obr->totvert++); /* save this for possible V wrapping */ - VECCOPY(v1->co, data); data += 3; + copy_v3_v3(v1->co, data); data += 3; if(orco) { v1->orco= orco; orco+= 3; orcoret++; } @@ -2548,7 +2548,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, for (v = 1; v < sizev; v++) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, data); data += 3; + copy_v3_v3(ver->co, data); data += 3; if(orco) { ver->orco= orco; orco+= 3; orcoret++; } @@ -2557,7 +2557,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, /* if V-cyclic, add extra vertices at end of the row */ if (dl->flag & DL_CYCL_U) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, v1->co); + copy_v3_v3(ver->co, v1->co); if(orco) { ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0); } @@ -2573,7 +2573,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, for (v = 0; v < nsizev; v++) { v1= RE_findOrAddVert(obr, startvert + v); ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, v1->co); + copy_v3_v3(ver->co, v1->co); if(orco) { ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v); } @@ -2602,7 +2602,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, normal_quad_v3( n1,vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); - VECCOPY(vlr->n, n1); + copy_v3_v3(vlr->n, n1); vlr->mat= matar[ dl->col]; vlr->ec= ME_V1V2+ME_V2V3; @@ -2670,10 +2670,10 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, add_v3_v3(n1, vlr2->n); vlr3= RE_findOrAddVlak(obr, UVTOINDEX(sizeu-1, 0)); /* (m,0) */ add_v3_v3(n1, vlr3->n); - VECCOPY(vlr->v3->n, n1); - VECCOPY(vlr1->v1->n, n1); - VECCOPY(vlr2->v2->n, n1); - VECCOPY(vlr3->v4->n, n1); + copy_v3_v3(vlr->v3->n, n1); + copy_v3_v3(vlr1->v1->n, n1); + copy_v3_v3(vlr2->v2->n, n1); + copy_v3_v3(vlr3->v4->n, n1); } for(a = startvert; a < obr->totvert; a++) { ver= RE_findOrAddVert(obr, a); @@ -2701,7 +2701,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, for(a=0; a<totvert; a++, mvert++) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, mvert->co); + copy_v3_v3(ver->co, mvert->co); mul_m4_v3(mat, ver->co); if(orco) { @@ -2913,7 +2913,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) for(a=0; a<dl->nr; a++, data+=3) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, data); + copy_v3_v3(ver->co, data); mul_m4_v3(mat, ver->co); @@ -2979,7 +2979,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) while(nr--) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, fp); + copy_v3_v3(ver->co, fp); mul_m4_v3(mat, ver->co); fp+= 3; @@ -3340,7 +3340,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) for(a=0; a<totvert; a++, mvert++) { ver= RE_findOrAddVert(obr, obr->totvert++); - VECCOPY(ver->co, mvert->co); + copy_v3_v3(ver->co, mvert->co); if(do_autosmooth==0) { /* autosmooth on original unrotated data to prevent differences between frames */ normal_short_to_float_v3(ver->n, mvert->no); mul_m4_v3(mat, ver->co); @@ -3782,7 +3782,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren"); lar->sunsky->effect_type = la->sun_effect_type; - VECCOPY(vec,ob->obmat[2]); + copy_v3_v3(vec,ob->obmat[2]); normalize_v3(vec); InitSunSky(lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness, @@ -4001,7 +4001,7 @@ void init_render_world(Render *re) cp[2]= 255.0f*re->wrld.horb; cp[3]= 1; - VECCOPY(re->grvec, re->viewmat[2]); + copy_v3_v3(re->grvec, re->viewmat[2]); normalize_v3(re->grvec); copy_m3_m4(re->imat, re->viewinv); @@ -4051,25 +4051,25 @@ static void set_phong_threshold(ObjectRen *obr) for(i=0; i<obr->totvlak; i++) { vlr= RE_findOrAddVlak(obr, i); if(vlr->flag & R_SMOOTH) { - dot= INPR(vlr->n, vlr->v1->n); + dot= dot_v3v3(vlr->n, vlr->v1->n); dot= ABS(dot); if(dot>0.9f) { thresh+= dot; tot++; } - dot= INPR(vlr->n, vlr->v2->n); + dot= dot_v3v3(vlr->n, vlr->v2->n); dot= ABS(dot); if(dot>0.9f) { thresh+= dot; tot++; } - dot= INPR(vlr->n, vlr->v3->n); + dot= dot_v3v3(vlr->n, vlr->v3->n); dot= ABS(dot); if(dot>0.9f) { thresh+= dot; tot++; } if(vlr->v4) { - dot= INPR(vlr->n, vlr->v4->n); + dot= dot_v3v3(vlr->n, vlr->v4->n); dot= ABS(dot); if(dot>0.9f) { thresh+= dot; tot++; @@ -4340,16 +4340,16 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset) strand_minmax(strand, smin, smax, width); } - VECCOPY(sbound->boundbox[0], smin); - VECCOPY(sbound->boundbox[1], smax); + copy_v3_v3(sbound->boundbox[0], smin); + copy_v3_v3(sbound->boundbox[1], smax); DO_MINMAX(smin, min, max); DO_MINMAX(smax, min, max); } } - VECCOPY(obr->boundbox[0], min); - VECCOPY(obr->boundbox[1], max); + copy_v3_v3(obr->boundbox[0], min); + copy_v3_v3(obr->boundbox[1], max); } } } @@ -4932,7 +4932,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* fill in instance variables for texturing */ set_dupli_tex_mat(re, obi, dob); if(dob->type != OB_DUPLIGROUP) { - VECCOPY(obi->dupliorco, dob->orco); + copy_v3_v3(obi->dupliorco, dob->orco); obi->dupliuv[0]= dob->uv[0]; obi->dupliuv[1]= dob->uv[1]; } @@ -4958,7 +4958,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp set_dupli_tex_mat(re, obi, dob); if(dob->type != OB_DUPLIGROUP) { - VECCOPY(obi->dupliorco, dob->orco); + copy_v3_v3(obi->dupliorco, dob->orco); obi->dupliuv[0]= dob->uv[0]; obi->dupliuv[1]= dob->uv[1]; } @@ -5064,7 +5064,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l /* still bad... doing all */ init_render_textures(re); - VECCOPY(amb, &re->wrld.ambr); + copy_v3_v3(amb, &re->wrld.ambr); init_render_materials(re->main, re->r.mode, amb); set_node_shader_lamp_loop(shade_material_loop); @@ -5216,7 +5216,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la } /* choose to use static, to prevent giving too many args to this call */ -static void speedvector_project(Render *re, float *zco, float *co, float *ho) +static void speedvector_project(Render *re, float zco[2], const float co[3], const float ho[4]) { static float pixelphix=0.0f, pixelphiy=0.0f, zmulx=0.0f, zmuly=0.0f; static int pano= 0; @@ -5251,7 +5251,7 @@ static void speedvector_project(Render *re, float *zco, float *co, float *ho) if(pano) { float vec[3], ang; /* angle between (0,0,-1) and (co) */ - VECCOPY(vec, co); + copy_v3_v3(vec, co); ang= saacos(-vec[2]/sqrt(vec[0]*vec[0] + vec[2]*vec[2])); if(vec[0]<0.0f) ang= -ang; @@ -5267,7 +5267,7 @@ static void speedvector_project(Render *re, float *zco, float *co, float *ho) } } -static void calculate_speedvector(float *vectors, int step, float winsq, float winroot, float *co, float *ho, float *speed) +static void calculate_speedvector(const float vectors[2], int step, float winsq, float winroot, const float co[3], const float ho[4], float speed[4]) { float zco[2], len; @@ -5764,7 +5764,7 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, /* still bad... doing all */ init_render_textures(re); - VECCOPY(amb, &re->wrld.ambr); + copy_v3_v3(amb, &re->wrld.ambr); init_render_materials(re->main, re->r.mode, amb); set_node_shader_lamp_loop(shade_material_loop); @@ -5860,7 +5860,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d) ms= me->msticky; for(a=0; a<me->totvert; a++, ms++, mvert++) { - VECCOPY(ho, mvert->co); + copy_v3_v3(ho, mvert->co); mul_m4_v3(mat, ho); projectverto(ho, re->winmat, ho); ms->co[0]= ho[0]/ho[3]; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 6d264951204..b290459a7c9 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -111,7 +111,7 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y) } } -int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texres) +int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres) { float fx, fy, val1, val2, val3; int x, y, retval; @@ -1019,7 +1019,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf) } -static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, float *dyt, TexResult *texres) +static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[3], float dyt[3], TexResult *texres) { TexResult texr; float fx, fy, minx, maxx, miny, maxy; @@ -1409,7 +1409,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, } -int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, float *DYT, TexResult *texres) +int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[3], const float DYT[3], TexResult *texres) { TexResult texr; float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[3], dyt[3]; @@ -1418,8 +1418,8 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, f // TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call, // make a local copy here so that original vecs remain untouched - VECCOPY(dxt, DXT); - VECCOPY(dyt, DYT); + copy_v3_v3(dxt, DXT); + copy_v3_v3(dyt, DYT); // anisotropic filtering if (tex->texfilter != TXF_BOX) diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 54137c62d22..36dd4eb9708 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1777,11 +1777,11 @@ void sample_occ(Render *re, ShadeInput *shi) if(cache->sample && cache->step) { sample= &cache->sample[(shi->ys-cache->y)*cache->w + (shi->xs-cache->x)]; - VECCOPY(sample->co, shi->co); - VECCOPY(sample->n, shi->vno); - VECCOPY(sample->ao, shi->ao); - VECCOPY(sample->env, shi->env); - VECCOPY(sample->indirect, shi->indirect); + copy_v3_v3(sample->co, shi->co); + copy_v3_v3(sample->n, shi->vno); + copy_v3_v3(sample->ao, shi->ao); + copy_v3_v3(sample->env, shi->env); + copy_v3_v3(sample->indirect, shi->indirect); sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]); sample->intensity= MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2])); sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2])); @@ -1872,11 +1872,11 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp) exclude.facenr= shi->vlr->index; sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect); - VECCOPY(sample->co, shi->co); - VECCOPY(sample->n, shi->vno); - VECCOPY(sample->ao, shi->ao); - VECCOPY(sample->env, shi->env); - VECCOPY(sample->indirect, shi->indirect); + copy_v3_v3(sample->co, shi->co); + copy_v3_v3(sample->n, shi->vno); + copy_v3_v3(sample->ao, shi->ao); + copy_v3_v3(sample->env, shi->env); + copy_v3_v3(sample->indirect, shi->indirect); sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]); sample->intensity= MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2])); sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2])); diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index febfea89f04..dd5deddece9 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -76,7 +76,7 @@ extern struct Render R; extern float hashvectf[]; -static void render_lighting_halo(HaloRen *har, float *colf) +static void render_lighting_halo(HaloRen *har, float col_r[3]) { GroupObject *go; LampRen *lar; @@ -246,9 +246,9 @@ static void render_lighting_halo(HaloRen *har, float *colf) if(ig<0.0f) ig= 0.0f; if(ib<0.0f) ib= 0.0f; - colf[0]*= ir; - colf[1]*= ig; - colf[2]*= ib; + col_r[0]*= ir; + col_r[1]*= ig; + col_r[2]*= ib; } @@ -502,8 +502,8 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, /* ------------------------------------------------------------------------- */ -/* Only view vector is important here. Result goes to colf[3] */ -void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread) +/* Only view vector is important here. Result goes to col_r[3] */ +void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const float dxyview[2], short thread) { float lo[3], zen[3], hor[3], blend, blendm; int skyflag; @@ -528,13 +528,13 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th blend= fabs(0.5f + view[1]); } - VECCOPY(hor, &R.wrld.horr); - VECCOPY(zen, &R.wrld.zenr); + copy_v3_v3(hor, &R.wrld.horr); + copy_v3_v3(zen, &R.wrld.zenr); /* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */ /* SKYBLEND is active, the texture and color blend are added. */ if(R.wrld.skytype & WO_SKYTEX) { - VECCOPY(lo, view); + copy_v3_v3(lo, view); if(R.wrld.skytype & WO_SKYREAL) { mul_m3_v3(R.imat, lo); @@ -550,19 +550,19 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th /* No clipping, no conversion! */ if(R.wrld.skytype & WO_SKYBLEND) { - colf[0] = (blendm*hor[0] + blend*zen[0]); - colf[1] = (blendm*hor[1] + blend*zen[1]); - colf[2] = (blendm*hor[2] + blend*zen[2]); + col_r[0] = (blendm*hor[0] + blend*zen[0]); + col_r[1] = (blendm*hor[1] + blend*zen[1]); + col_r[2] = (blendm*hor[2] + blend*zen[2]); } else { /* Done when a texture was grabbed. */ - colf[0]= hor[0]; - colf[1]= hor[1]; - colf[2]= hor[2]; + col_r[0]= hor[0]; + col_r[1]= hor[1]; + col_r[2]= hor[2]; } } /* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/ -void shadeSunView(float *colf, float *view) +void shadeSunView(float col_r[3], const float view[3]) { GroupObject *go; LampRen *lar; @@ -576,9 +576,8 @@ void shadeSunView(float *colf, float *view) float colorxyz[3]; if(do_init) { - - VECCOPY(sview, view); - normalize_v3(sview); + + normalize_v3_v3(sview, view); mul_m3_v3(R.imat, sview); if (sview[2] < 0.0f) sview[2] = 0.0f; @@ -590,7 +589,7 @@ void shadeSunView(float *colf, float *view) xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &sun_collector[0], &sun_collector[1], &sun_collector[2], lar->sunsky->sky_colorspace); - ramp_blend(lar->sunsky->skyblendtype, colf, colf+1, colf+2, lar->sunsky->skyblendfac, sun_collector); + ramp_blend(lar->sunsky->skyblendtype, col_r, col_r+1, col_r+2, lar->sunsky->skyblendfac, sun_collector); } } } @@ -599,7 +598,7 @@ void shadeSunView(float *colf, float *view) /* Stuff the sky color into the collector. */ -void shadeSkyPixel(float *collector, float fx, float fy, short thread) +void shadeSkyPixel(float collector[4], float fx, float fy, short thread) { float view[3], dxyview[2]; @@ -649,10 +648,10 @@ void shadeSkyPixel(float *collector, float fx, float fy, short thread) } /* aerial perspective */ -void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance) +void shadeAtmPixel(struct SunSky *sunsky, float collector[3], float fx, float fy, float distance) { float view[3]; - + calc_view_vector(view, fx, fy); normalize_v3(view); /*mul_m3_v3(R.imat, view);*/ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index cf1fae81eb5..ad592609ce6 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -505,7 +505,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres) if(texres->nor) { - VECCOPY(texres->nor, nor); + copy_v3_v3(texres->nor, nor); tex_normal_derivate(tex, texres); if(tex->stype==TEX_WALLOUT) { @@ -755,9 +755,9 @@ static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex if(pit && pit->doit) { if(texres->nor) { if (pit->version < 6) { - VECCOPY(pit->result+5, texres->nor); + copy_v3_v3(pit->result+5, texres->nor); } else { - VECCOPY(result+5, texres->nor); + copy_v3_v3(result+5, texres->nor); } } if (pit->version < 6) { @@ -781,9 +781,9 @@ static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex if(rgbnor & TEX_NOR) { if(texres->nor) { if (pit->version < 6) { - VECCOPY(texres->nor, pit->result+5); + copy_v3_v3(texres->nor, pit->result+5); } else { - VECCOPY(texres->nor, result+5); + copy_v3_v3(texres->nor, result+5); } } } @@ -820,7 +820,7 @@ static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float nor[0]= x; nor[1]= y; nor[2]= z; // use local render coord } else { - VECCOPY(nor, n); + copy_v3_v3(nor, n); } mul_mat3_m4_v3(R.viewinv, nor); @@ -914,7 +914,7 @@ static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *ad if(n==NULL) return 0; - VECCOPY(nor, n); + copy_v3_v3(nor, n); if(ob) mul_mat3_m4_v3(ob->imat, nor); x1= fabs(nor[0]); @@ -1219,7 +1219,7 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, /* ton: added this, for Blender convention reason. * artificer: added the use of tmpvec to avoid scaling texvec */ - VECCOPY(tmpvec, texvec); + copy_v3_v3(tmpvec, texvec); mul_v3_fl(tmpvec, 1.0f/tex->noisesize); switch(tex->stype) { @@ -1241,7 +1241,7 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, /* ton: added this, for Blender convention reason. * artificer: added the use of tmpvec to avoid scaling texvec */ - VECCOPY(tmpvec, texvec); + copy_v3_v3(tmpvec, texvec); mul_v3_fl(tmpvec, 1.0f/tex->noisesize); retval= voronoiTex(tex, tmpvec, texres); @@ -1250,7 +1250,7 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, /* ton: added this, for Blender convention reason. * artificer: added the use of tmpvec to avoid scaling texvec */ - VECCOPY(tmpvec, texvec); + copy_v3_v3(tmpvec, texvec); mul_v3_fl(tmpvec, 1.0f/tex->noisesize); retval= mg_distNoiseTex(tex, tmpvec, texres); @@ -1374,7 +1374,7 @@ int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres) /* in = destination, tex = texture, out = previous color */ /* fact = texture strength, facg = button strength value */ -void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype) +void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype) { float facm, col; @@ -1477,32 +1477,32 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg case MTEX_BLEND_HUE: fact*= facg; - VECCOPY(in, out); + copy_v3_v3(in, out); ramp_blend(MA_RAMP_HUE, in, in+1, in+2, fact, tex); break; case MTEX_BLEND_SAT: fact*= facg; - VECCOPY(in, out); + copy_v3_v3(in, out); ramp_blend(MA_RAMP_SAT, in, in+1, in+2, fact, tex); break; case MTEX_BLEND_VAL: fact*= facg; - VECCOPY(in, out); + copy_v3_v3(in, out); ramp_blend(MA_RAMP_VAL, in, in+1, in+2, fact, tex); break; case MTEX_BLEND_COLOR: fact*= facg; - VECCOPY(in, out); + copy_v3_v3(in, out); ramp_blend(MA_RAMP_COLOR, in, in+1, in+2, fact, tex); break; case MTEX_SOFT_LIGHT: fact*= facg; - VECCOPY(in, out); + copy_v3_v3(in, out); ramp_blend(MA_RAMP_SOFT, in, in+1, in+2, fact, tex); break; case MTEX_LIN_LIGHT: fact*= facg; - VECCOPY(in, out); + copy_v3_v3(in, out); ramp_blend(MA_RAMP_LINEAR, in, in+1, in+2, fact, tex); break; } @@ -1924,8 +1924,8 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code if( !ntap_bump->init_done ) { - VECCOPY(ntap_bump->vNacc, shi->vn); - VECCOPY(ntap_bump->vNorg, shi->vn); + copy_v3_v3(ntap_bump->vNacc, shi->vn); + copy_v3_v3(ntap_bump->vNorg, shi->vn); ntap_bump->fPrevMagnitude = 1.0f; ntap_bump->iPrevBumpSpace = 0; @@ -2056,9 +2056,9 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T float obj2view[3][3], view2obj[3][3], tmp[4][4]; // local copies of derivatives and normal float dPdx[3], dPdy[3], vN[3]; - VECCOPY(dPdx, shi->dxco); - VECCOPY(dPdy, shi->dyco); - VECCOPY(vN, ntap_bump->vNorg); + copy_v3_v3(dPdx, shi->dxco); + copy_v3_v3(dPdy, shi->dyco); + copy_v3_v3(vN, ntap_bump->vNorg); if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) { // TODO: these calculations happen for every pixel! @@ -2200,14 +2200,14 @@ void do_material_tex(ShadeInput *shi) co= tempvec; dx= dxt; dy= dyt; - VECCOPY(tempvec, shi->co); + copy_v3_v3(tempvec, shi->co); if(mtex->texflag & MTEX_OB_DUPLI_ORIG) if(shi->obi && shi->obi->duplitexmat) mul_m4_v3(shi->obi->duplitexmat, tempvec); mul_m4_v3(ob->imat_ren, tempvec); if(shi->osatex) { - VECCOPY(dxt, shi->dxco); - VECCOPY(dyt, shi->dyco); + copy_v3_v3(dxt, shi->dxco); + copy_v3_v3(dyt, shi->dyco); mul_mat3_m4_v3(ob->imat_ren, dxt); mul_mat3_m4_v3(ob->imat_ren, dyt); } @@ -2369,7 +2369,7 @@ void do_material_tex(ShadeInput *shi) float *warpnor= texres.nor, warpnor_[3]; if(use_ntap_bump) { - VECCOPY(warpnor_, texres.nor); + copy_v3_v3(warpnor_, texres.nor); warpnor= warpnor_; normalize_v3(warpnor_); } @@ -2485,7 +2485,7 @@ void do_material_tex(ShadeInput *shi) else { float nor[3]; - VECCOPY(nor, texres.nor); + copy_v3_v3(nor, texres.nor); if(mtex->normapspace == MTEX_NSPACE_CAMERA); else if(mtex->normapspace == MTEX_NSPACE_WORLD) { @@ -2526,7 +2526,7 @@ void do_material_tex(ShadeInput *shi) nor[1]= Tnor*norfac*texres.nor[1]; nor[2]= Tnor*norfac*texres.nor[2]; - dot= 0.5f + 0.5f*INPR(nor, shi->vn); + dot= 0.5f + 0.5f * dot_v3v3(nor, shi->vn); shi->vn[0]+= dot*nor[0]; shi->vn[1]+= dot*nor[1]; @@ -2658,7 +2658,7 @@ void do_material_tex(ShadeInput *shi) } -void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, float *val) +void do_volume_tex(ShadeInput *shi, const float xyz[3], int mapto_flag, float col[3], float *val) { MTex *mtex; Tex *tex; @@ -2687,7 +2687,7 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa if(mtex->texco==TEXCO_OBJECT) { Object *ob= mtex->object; if(ob) { - VECCOPY(co, xyz); + copy_v3_v3(co, xyz); if(mtex->texflag & MTEX_OB_DUPLI_ORIG) { if(shi->obi && shi->obi->duplitexmat) mul_m4_v3(shi->obi->duplitexmat, co); @@ -2699,16 +2699,16 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa else if(mtex->texco==TEXCO_ORCO) { if(mtex->texflag & MTEX_DUPLI_MAPTO) { - VECCOPY(co, shi->duplilo); + copy_v3_v3(co, shi->duplilo); } else { Object *ob= shi->obi->ob; - VECCOPY(co, xyz); + copy_v3_v3(co, xyz); mul_m4_v3(ob->imat_ren, co); } } else if(mtex->texco==TEXCO_GLOB) { - VECCOPY(co, xyz); + copy_v3_v3(co, xyz); mul_m4_v3(R.viewinv, co); } else continue; // can happen when texco defines disappear and it renders old files @@ -2838,7 +2838,7 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa /* ------------------------------------------------------------------------- */ -void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) +void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) { MTex *mtex; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; @@ -2945,23 +2945,23 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) if(mtex->blendtype==MTEX_SUB) fact= -fact; if(mtex->blendtype==MTEX_BLEND) { - colf[0]= (fact*texres.tr + facm*har->r); - colf[1]= (fact*texres.tg + facm*har->g); - colf[2]= (fact*texres.tb + facm*har->b); + col_r[0]= (fact*texres.tr + facm*har->r); + col_r[1]= (fact*texres.tg + facm*har->g); + col_r[2]= (fact*texres.tb + facm*har->b); } else if(mtex->blendtype==MTEX_MUL) { - colf[0]= (facm+fact*texres.tr)*har->r; - colf[1]= (facm+fact*texres.tg)*har->g; - colf[2]= (facm+fact*texres.tb)*har->b; + col_r[0]= (facm+fact*texres.tr)*har->r; + col_r[1]= (facm+fact*texres.tg)*har->g; + col_r[2]= (facm+fact*texres.tb)*har->b; } else { - colf[0]= (fact*texres.tr + har->r); - colf[1]= (fact*texres.tg + har->g); - colf[2]= (fact*texres.tb + har->b); + col_r[0]= (fact*texres.tr + har->r); + col_r[1]= (fact*texres.tg + har->g); + col_r[2]= (fact*texres.tb + har->b); - CLAMP(colf[0], 0.0f, 1.0f); - CLAMP(colf[1], 0.0f, 1.0f); - CLAMP(colf[2], 0.0f, 1.0f); + CLAMP(col_r[0], 0.0f, 1.0f); + CLAMP(col_r[1], 0.0f, 1.0f); + CLAMP(col_r[2], 0.0f, 1.0f); } } if(mtex->mapto & MAP_ALPHA) { @@ -2970,14 +2970,14 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); } - colf[3]*= texres.tin; + col_r[3]*= texres.tin; } } /* ------------------------------------------------------------------------- */ /* hor and zen are RGB vectors, blend is 1 float, should all be initialized */ -void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread) +void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread) { MTex *mtex; Tex *tex; @@ -3054,7 +3054,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f break; case TEXCO_OBJECT: if(mtex->object) { - VECCOPY(tempvec, lo); + copy_v3_v3(tempvec, lo); mul_m4_v3(mtex->object->imat_ren, tempvec); co= tempvec; } @@ -3062,16 +3062,16 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f case TEXCO_GLOB: if(rco) { - VECCOPY(tempvec, rco); + copy_v3_v3(tempvec, rco); mul_m4_v3(R.viewinv, tempvec); co= tempvec; } else co= lo; -// VECCOPY(shi->dxgl, shi->dxco); +// copy_v3_v3(shi->dxgl, shi->dxco); // mul_m3_v3(R.imat, shi->dxco); -// VECCOPY(shi->dygl, shi->dyco); +// copy_v3_v3(shi->dygl, shi->dyco); // mul_m3_v3(R.imat, shi->dyco); break; } @@ -3172,9 +3172,9 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f } /* ------------------------------------------------------------------------- */ -/* colf supposed to be initialized with la->r,g,b */ +/* col_r supposed to be initialized with la->r,g,b */ -void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int effect) +void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r[3], int effect) { Object *ob; MTex *mtex; @@ -3203,11 +3203,11 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef co= tempvec; dx= dxt; dy= dyt; - VECCOPY(tempvec, shi->co); + copy_v3_v3(tempvec, shi->co); mul_m4_v3(ob->imat_ren, tempvec); if(shi->osatex) { - VECCOPY(dxt, shi->dxco); - VECCOPY(dyt, shi->dyco); + copy_v3_v3(dxt, shi->dxco); + copy_v3_v3(dyt, shi->dyco); mul_mat3_m4_v3(ob->imat_ren, dxt); mul_mat3_m4_v3(ob->imat_ren, dyt); } @@ -3219,12 +3219,12 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef } else if(mtex->texco==TEXCO_GLOB) { co= shi->gl; dx= shi->dxco; dy= shi->dyco; - VECCOPY(shi->gl, shi->co); + copy_v3_v3(shi->gl, shi->co); mul_m4_v3(R.viewinv, shi->gl); } else if(mtex->texco==TEXCO_VIEW) { - VECCOPY(tempvec, lavec); + copy_v3_v3(tempvec, lavec); mul_m3_v3(la->imat, tempvec); if(la->type==LA_SPOT) { @@ -3238,8 +3238,8 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef dx= dxt; dy= dyt; if(shi->osatex) { - VECCOPY(dxt, shi->dxlv); - VECCOPY(dyt, shi->dylv); + copy_v3_v3(dxt, shi->dxlv); + copy_v3_v3(dyt, shi->dylv); /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ mul_m3_v3(la->imat, dxt); mul_m3_v3(la->imat, dyt); @@ -3356,7 +3356,7 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef col[1]= texres.tg*la->energy; col[2]= texres.tb*la->energy; - texture_rgb_blend(colf, col, colf, texres.tin, mtex->colfac, mtex->blendtype); + texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->colfac, mtex->blendtype); } } } @@ -3364,7 +3364,7 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef /* ------------------------------------------------------------------------- */ -int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta, const int thread) +int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread) { Tex *tex; TexResult texr; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index b66740c87ba..16bbe1ca5c2 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -128,7 +128,7 @@ void calc_view_vector(float *view, float x, float y) } } -void calc_renderco_ortho(float *co, float x, float y, int z) +void calc_renderco_ortho(float co[3], float x, float y, int z) { /* x and y 3d coordinate can be derived from pixel coord and winmat */ float fx= 2.0f/(R.winx*R.winmat[0][0]); @@ -142,7 +142,7 @@ void calc_renderco_ortho(float *co, float x, float y, int z) co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] ); } -void calc_renderco_zbuf(float *co, float *view, int z) +void calc_renderco_zbuf(float co[3], float *view, int z) { float fac, zco; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 0c5ad0475ab..7a39342ac8d 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -428,7 +428,7 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) surfnor= RE_vlakren_get_surfnor(obr, vlr, 0); if(surfnor) { surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1); - VECCOPY(surfnor1, surfnor); + copy_v3_v3(surfnor1, surfnor); } tangent= RE_vlakren_get_nmap_tangent(obr, vlr, 0); @@ -451,13 +451,12 @@ void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen * float (*nmat)[3]= obi->nmat; if(obi->flag & R_TRANSFORMED) { - VECCOPY(nor, vlr->n); - - mul_m3_v3(nmat, nor); + mul_v3_m3v3(nor, nmat, vlr->n); normalize_v3(nor); } - else - VECCOPY(nor, vlr->n); + else { + copy_v3_v3(nor, vlr->n); + } } void RE_set_customdata_names(ObjectRen *obr, CustomData *data) @@ -953,7 +952,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f } har= RE_findOrAddHalo(obr, obr->tothalo++); - VECCOPY(har->co, vec); + copy_v3_v3(har->co, vec); har->hasize= hasize; /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ @@ -1009,7 +1008,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f else { mtex= ma->mtex[0]; - VECCOPY(texvec, vec); + copy_v3_v3(texvec, vec); if(mtex->texco & TEXCO_NORM) { ; @@ -1022,7 +1021,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f } else { if(orco) { - VECCOPY(texvec, orco); + copy_v3_v3(texvec, orco); } } @@ -1067,7 +1066,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater } har= RE_findOrAddHalo(obr, obr->tothalo++); - VECCOPY(har->co, vec); + copy_v3_v3(har->co, vec); har->hasize= hasize; /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ @@ -1123,7 +1122,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater for(i=0; i<MAX_MTEX; i++) if(ma->mtex[i] && (ma->septex & (1<<i))==0) { mtex= ma->mtex[i]; - VECCOPY(texvec, vec); + copy_v3_v3(texvec, vec); if(mtex->texco & TEXCO_NORM) { ; @@ -1133,7 +1132,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater mul_m4_v3(mtex->object->imat_ren,texvec); } else if(mtex->texco & TEXCO_GLOB){ - VECCOPY(texvec,vec); + copy_v3_v3(texvec,vec); } else if(mtex->texco & TEXCO_UV && uvco){ int uv_index=CustomData_get_named_layer_index(&dm->faceData,CD_MTFACE,mtex->uvname); @@ -1153,7 +1152,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater texvec[2] = pa_co[2]; } else if(orco) { - VECCOPY(texvec, orco); + copy_v3_v3(texvec, orco); } hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0); @@ -1238,7 +1237,7 @@ static int panotestclip(Render *re, int do_pano, float *v) - shadow buffering (shadbuf.c) */ -void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) +void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) { ObjectRen *obr; HaloRen *har = NULL; @@ -1264,7 +1263,7 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2]; } else { - VECCOPY(vec, har->co); + copy_v3_v3(vec, har->co); } projectfunc(vec, re->winmat, hoco); diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 5860c395b07..e4b2a0cf1d1 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1099,7 +1099,7 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int } } -static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, float co[3]) +static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, const float co[3]) { float hco[4], size= 0.5f*(float)shb->size; @@ -1115,7 +1115,7 @@ static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, flo /* the externally called shadow testing (reading) function */ /* return 1.0: no shadow at all */ -float testshadowbuf(Render *re, ShadBuf *shb, float *co, float *dxco, float *dyco, float inp, float mat_bias) +float testshadowbuf(Render *re, ShadBuf *shb, const float co[3], const float dxco[3], const float dyco[3], float inp, float mat_bias) { ShadSampleBuf *shsample; float fac, dco[3], dx[3], dy[3], shadfac=0.0f; @@ -1291,7 +1291,7 @@ static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, i } -float shadow_halo(LampRen *lar, float *p1, float *p2) +float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) { /* p1 p2 already are rotated in spot-space */ ShadBuf *shb= lar->shb; @@ -1469,7 +1469,7 @@ static void init_box(Boxf *box) } /* use v1 to calculate boundbox */ -static void bound_boxf(Boxf *box, float *v1) +static void bound_boxf(Boxf *box, const float v1[3]) { if(v1[0] < box->xmin) box->xmin= v1[0]; if(v1[0] > box->xmax) box->xmax= v1[0]; @@ -1480,7 +1480,7 @@ static void bound_boxf(Boxf *box, float *v1) } /* use v1 to calculate boundbox */ -static void bound_rectf(rctf *box, float *v1) +static void bound_rectf(rctf *box, const float v1[2]) { if(v1[0] < box->xmin) box->xmin= v1[0]; if(v1[0] > box->xmax) box->xmax= v1[0]; @@ -1639,24 +1639,17 @@ static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample return 0; } -static float VecLen2f( float *v1, float *v2) -{ - float x= v1[0]-v2[0]; - float y= v1[1]-v2[1]; - return (float)sqrt(x*x+y*y); -} - /* initialize vars in face, for optimal point-in-face test */ static void bspface_init_strand(BSPFace *face) { - face->radline= 0.5f*VecLen2f(face->v1, face->v2); + face->radline= 0.5f* len_v2v2(face->v1, face->v2); mid_v3_v3v3(face->vec1, face->v1, face->v2); if(face->v4) mid_v3_v3v3(face->vec2, face->v3, face->v4); else - VECCOPY(face->vec2, face->v3); + copy_v3_v3(face->vec2, face->v3); face->rc[0]= face->vec2[0]-face->vec1[0]; face->rc[1]= face->vec2[1]-face->vec1[1]; @@ -1671,7 +1664,7 @@ static void bspface_init_strand(BSPFace *face) } /* brought back to a simple 2d case */ -static int point_behind_strand(float *p, BSPFace *face) +static int point_behind_strand(const float p[3], BSPFace *face) { /* v1 - v2 is radius, v1 - v3 length */ float dist, rc[2], pt[2]; @@ -1712,7 +1705,7 @@ static int point_behind_strand(float *p, BSPFace *face) /* return 1 if inside. code derived from src/parametrizer.c */ -static int point_behind_tria2d(float *p, float *v1, float *v2, float *v3) +static int point_behind_tria2d(const float p[3], const float v1[3], const float v2[3], const float v3[3]) { float a[2], c[2], h[2], div; float u, v; @@ -1751,7 +1744,7 @@ static int point_behind_tria2d(float *p, float *v1, float *v2, float *v3) /* tested these calls, but it gives inaccuracy, 'side' cannot be found reliably using v3 */ /* check if line v1-v2 has all rect points on other side of point v3 */ -static int rect_outside_line(rctf *rect, float *v1, float *v2, float *v3) +static int rect_outside_line(rctf *rect, const float v1[3], const float v2[3], const float v3[3]) { float a, b, c; int side; @@ -1772,7 +1765,7 @@ static int rect_outside_line(rctf *rect, float *v1, float *v2, float *v3) } /* check if one of the triangle edges separates all rect points on 1 side */ -static int rect_isect_tria(rctf *rect, float *v1, float *v2, float *v3) +static int rect_isect_tria(rctf *rect, const float v1[3], const float v2[3], const float v3[3]) { if(rect_outside_line(rect, v1, v2, v3)) return 0; @@ -1935,7 +1928,7 @@ static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr, float *v1, float isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face); } -static int testclip_minmax(float *ho, float *minmax) +static int testclip_minmax(const float ho[4], const float minmax[4]) { float wco= ho[3]; int flag= 0; @@ -2064,7 +2057,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) } /* returns 1 when the viewpixel is visible in lampbuffer */ -static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float *co) +static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float co_r[3]) { float hoco[4], v1[3], nor[3]; float dface, fac, siz; @@ -2123,12 +2116,12 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *v return 0; siz= 0.5f*(float)shb->size; - co[0]= siz*(1.0f+hoco[0]/hoco[3]) -0.5f; - co[1]= siz*(1.0f+hoco[1]/hoco[3]) -0.5f; - co[2]= ((float)0x7FFFFFFF)*(hoco[2]/hoco[3]); + co_r[0]= siz*(1.0f+hoco[0]/hoco[3]) -0.5f; + co_r[1]= siz*(1.0f+hoco[1]/hoco[3]) -0.5f; + co_r[2]= ((float)0x7FFFFFFF)*(hoco[2]/hoco[3]); /* XXXX bias, much less than normal shadbuf, or do we need a constant? */ - co[2] -= 0.05f*shb->bias; + co_r[2] -= 0.05f*shb->bias; return 1; } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index eab66aaf2ec..128900d1fd2 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -114,10 +114,8 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) float fac= shi->translucency; shade_input_init_material(shi); - - VECCOPY(shi->vn, shi->vno); - VECMUL(shi->vn, -1.0f); - VECMUL(shi->facenor, -1.0f); + negate_v3_v3(shi->vn, shi->vno); + negate_v3(shi->facenor); shi->depth++; /* hack to get real shadow now */ shade_lamp_loop(shi, &shr_t); shi->depth--; @@ -184,8 +182,8 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) /* copy additional passes */ if(shi->passflag & (SCE_PASS_VECTOR|SCE_PASS_NORMAL)) { - QUATCOPY(shr->winspeed, shi->winspeed); - VECCOPY(shr->nor, shi->vn); + copy_v4_v4(shr->winspeed, shi->winspeed); + copy_v3_v3(shr->nor, shi->vn); } /* MIST */ @@ -286,9 +284,9 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen /* calculate vertexnormals */ if(vlr->flag & R_SMOOTH) { - VECCOPY(shi->n1, shi->v1->n); - VECCOPY(shi->n2, shi->v2->n); - VECCOPY(shi->n3, shi->v3->n); + copy_v3_v3(shi->n1, shi->v1->n); + copy_v3_v3(shi->n2, shi->v2->n); + copy_v3_v3(shi->n3, shi->v3->n); if(obi->flag & R_TRANSFORMED) { mul_m3_v3(obi->nmat, shi->n1); normalize_v3(shi->n1); @@ -341,26 +339,26 @@ void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spo shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */ /* shade_input_set_viewco equivalent */ - VECCOPY(shi->co, spoint->co); - VECCOPY(shi->view, shi->co); + copy_v3_v3(shi->co, spoint->co); + copy_v3_v3(shi->view, shi->co); normalize_v3(shi->view); shi->xs= (int)spoint->x; shi->ys= (int)spoint->y; if(shi->osatex || (R.r.mode & R_SHADOW)) { - VECCOPY(shi->dxco, spoint->dtco); - VECCOPY(shi->dyco, spoint->dsco); + copy_v3_v3(shi->dxco, spoint->dtco); + copy_v3_v3(shi->dyco, spoint->dsco); } /* dxview, dyview, not supported */ /* facenormal, simply viewco flipped */ - VECCOPY(shi->facenor, spoint->nor); + copy_v3_v3(shi->facenor, spoint->nor); /* shade_input_set_normals equivalent */ if(shi->mat->mode & MA_TANGENT_STR) { - VECCOPY(shi->vn, spoint->tan) + copy_v3_v3(shi->vn, spoint->tan); } else { float cross[3]; @@ -369,11 +367,11 @@ void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spo cross_v3_v3v3(shi->vn, cross, spoint->tan); normalize_v3(shi->vn); - if(INPR(shi->vn, shi->view) < 0.0f) + if(dot_v3v3(shi->vn, shi->view) < 0.0f) negate_v3(shi->vn); } - VECCOPY(shi->vno, shi->vn); + copy_v3_v3(shi->vno, shi->vn); } void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert *svert, StrandPoint *spoint) @@ -393,17 +391,17 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert } if(mode & (MA_TANGENT_V|MA_NORMAP_TANG)) { - VECCOPY(shi->tang, spoint->tan); - VECCOPY(shi->nmaptang, spoint->tan); + copy_v3_v3(shi->tang, spoint->tan); + copy_v3_v3(shi->nmaptang, spoint->tan); } if(mode & MA_STR_SURFDIFF) { float *surfnor= RE_strandren_get_surfnor(obr, strand, 0); if(surfnor) - VECCOPY(shi->surfnor, surfnor) + copy_v3_v3(shi->surfnor, surfnor); else - VECCOPY(shi->surfnor, shi->vn) + copy_v3_v3(shi->surfnor, shi->vn); if(shi->mat->strand_surfnor > 0.0f) { shi->surfdist= 0.0f; @@ -418,7 +416,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert speed= RE_strandren_get_winspeed(shi->obi, strand, 0); if(speed) - QUATCOPY(shi->winspeed, speed) + copy_v4_v4(shi->winspeed, speed); else shi->winspeed[0]= shi->winspeed[1]= shi->winspeed[2]= shi->winspeed[3]= 0.0f; } @@ -426,18 +424,18 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert /* shade_input_set_shade_texco equivalent */ if(texco & NEED_UV) { if(texco & TEXCO_ORCO) { - VECCOPY(shi->lo, strand->orco); + copy_v3_v3(shi->lo, strand->orco); /* no shi->osatex, orco derivatives are zero */ } if(texco & TEXCO_GLOB) { - VECCOPY(shi->gl, shi->co); + copy_v3_v3(shi->gl, shi->co); mul_m4_v3(R.viewinv, shi->gl); if(shi->osatex) { - VECCOPY(shi->dxgl, shi->dxco); + copy_v3_v3(shi->dxgl, shi->dxco); mul_mat3_m4_v3(R.viewinv, shi->dxgl); - VECCOPY(shi->dygl, shi->dyco); + copy_v3_v3(shi->dygl, shi->dyco); mul_mat3_m4_v3(R.viewinv, shi->dygl); } } @@ -586,7 +584,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert } /* from scanline pixel coordinates to 3d coordinates, requires set_triangle */ -void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float *view, float *dxyview, float *co, float *dxco, float *dyco) +void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]) { /* returns not normalized, so is in viewplane coords */ calc_view_vector(view, x, y); @@ -603,7 +601,7 @@ void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float * /* for non-wire, intersect with the triangle to get the exact coord */ float fac, dface, v1[3]; - VECCOPY(v1, shi->v1->co); + copy_v3_v3(v1, shi->v1->co); if(shi->obi->flag & R_TRANSFORMED) mul_m4_v3(shi->obi->mat, v1); @@ -721,9 +719,9 @@ void shade_input_set_uv(ShadeInput *shi) if((vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) { float v1[3], v2[3], v3[3]; - VECCOPY(v1, shi->v1->co); - VECCOPY(v2, shi->v2->co); - VECCOPY(v3, shi->v3->co); + copy_v3_v3(v1, shi->v1->co); + copy_v3_v3(v2, shi->v2->co); + copy_v3_v3(v3, shi->v3->co); if(shi->obi->flag & R_TRANSFORMED) { mul_m4_v3(shi->obi->mat, v1); @@ -822,18 +820,18 @@ void shade_input_set_normals(ShadeInput *shi) shi->vn[2]= l*n3[2]-u*n1[2]-v*n2[2]; // use unnormalized normal (closer to games) - VECCOPY(shi->nmapnorm, shi->vn); + copy_v3_v3(shi->nmapnorm, shi->vn); normalize_v3(shi->vn); } else { - VECCOPY(shi->vn, shi->facenor); - VECCOPY(shi->nmapnorm, shi->vn); + copy_v3_v3(shi->vn, shi->facenor); + copy_v3_v3(shi->nmapnorm, shi->vn); } /* used in nodes */ - VECCOPY(shi->vno, shi->vn); + copy_v3_v3(shi->vno, shi->vn); /* flip normals to viewing direction */ if(!(shi->vlr->flag & R_TANGENT)) @@ -856,18 +854,18 @@ void shade_input_set_vertex_normals(ShadeInput *shi) shi->vn[2]= l*n3[2]-u*n1[2]-v*n2[2]; // use unnormalized normal (closer to games) - VECCOPY(shi->nmapnorm, shi->vn); + copy_v3_v3(shi->nmapnorm, shi->vn); normalize_v3(shi->vn); } else { - VECCOPY(shi->vn, shi->facenor); - VECCOPY(shi->nmapnorm, shi->vn); + copy_v3_v3(shi->vn, shi->facenor); + copy_v3_v3(shi->nmapnorm, shi->vn); } /* used in nodes */ - VECCOPY(shi->vno, shi->vn); + copy_v3_v3(shi->vno, shi->vn); } @@ -956,7 +954,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) mul_m3_v3(obi->nmat, shi->tang); normalize_v3(shi->tang); - VECCOPY(shi->nmaptang, shi->tang); + copy_v3_v3(shi->nmaptang, shi->tang); } } @@ -969,9 +967,9 @@ void shade_input_set_shade_texco(ShadeInput *shi) vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3); - VECCOPY(c0, &tangent[j1*4]); - VECCOPY(c1, &tangent[j2*4]); - VECCOPY(c2, &tangent[j3*4]); + copy_v3_v3(c0, &tangent[j1*4]); + copy_v3_v3(c1, &tangent[j2*4]); + copy_v3_v3(c2, &tangent[j3*4]); // keeping tangents normalized at vertex level // corresponds better to how it's done in game engines @@ -999,12 +997,12 @@ void shade_input_set_shade_texco(ShadeInput *shi) float *surfnor= RE_vlakren_get_surfnor(obr, shi->vlr, 0); if(surfnor) { - VECCOPY(shi->surfnor, surfnor) + copy_v3_v3(shi->surfnor, surfnor); if(obi->flag & R_TRANSFORMED) mul_m3_v3(obi->nmat, shi->surfnor); } else - VECCOPY(shi->surfnor, shi->vn) + copy_v3_v3(shi->surfnor, shi->vn); shi->surfdist= 0.0f; } @@ -1057,16 +1055,16 @@ void shade_input_set_shade_texco(ShadeInput *shi) } } - VECCOPY(shi->duplilo, obi->dupliorco); + copy_v3_v3(shi->duplilo, obi->dupliorco); } if(texco & TEXCO_GLOB) { - VECCOPY(shi->gl, shi->co); + copy_v3_v3(shi->gl, shi->co); mul_m4_v3(R.viewinv, shi->gl); if(shi->osatex) { - VECCOPY(shi->dxgl, shi->dxco); + copy_v3_v3(shi->dxgl, shi->dxco); mul_mat3_m4_v3(R.viewinv, shi->dxgl); - VECCOPY(shi->dygl, shi->dyco); + copy_v3_v3(shi->dygl, shi->dyco); mul_mat3_m4_v3(R.viewinv, shi->dygl); } } diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 30632586b04..431b2839c25 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -85,7 +85,7 @@ static void fogcolor(float *colf, float *rco, float *view) hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb; zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb; - VECCOPY(vec, rco); + copy_v3_v3(vec, rco); /* we loop from cur coord to mist start in steps */ stepsize= 1.0f; @@ -486,8 +486,8 @@ static float area_lamp_energy_multisample(LampRen *lar, float *co, float *vn) int a= lar->ray_totsamp; /* test if co is behind lamp */ - VECSUB(vec, co, lar->co); - if(INPR(vec, lar->vec) < 0.0f) + sub_v3_v3v3(vec, co, lar->co); + if(dot_v3v3(vec, lar->vec) < 0.0f) return 0.0f; while(a--) { @@ -1119,21 +1119,21 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist) { if(lar->type==LA_SUN || lar->type==LA_HEMI) { *dist= 1.0f; - VECCOPY(lv, lar->vec); + copy_v3_v3(lv, lar->vec); return 1.0f; } else { float visifac= 1.0f, t; - VECSUB(lv, co, lar->co); - *dist= sqrt( INPR(lv, lv)); + sub_v3_v3v3(lv, co, lar->co); + *dist= sqrtf(dot_v3v3(lv, lv)); t= 1.0f/dist[0]; - VECMUL(lv, t); + mul_v3_fl(lv, t); /* area type has no quad or sphere option */ if(lar->type==LA_AREA) { /* area is single sided */ - //if(INPR(lv, lar->vec) > 0.0f) + //if(dot_v3v3(lv, lar->vec) > 0.0f) // visifac= 1.0f; //else // visifac= 0.0f; @@ -1179,11 +1179,11 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist) float inpr; if(lar->mode & LA_SQUARE) { - if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) { + if(dot_v3v3(lv, lar->vec) > 0.0f) { float lvrot[3], x; /* rotate view to lampspace */ - VECCOPY(lvrot, lv); + copy_v3_v3(lvrot, lv); mul_m3_v3(lar->imat, lvrot); x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); @@ -1279,7 +1279,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int cross_v3_v3v3(cross, shi->surfnor, vn); cross_v3_v3v3(nstrand, vn, cross); - blend= INPR(nstrand, shi->surfnor); + blend= dot_v3v3(nstrand, shi->surfnor); blend= 1.0f - blend; CLAMP(blend, 0.0f, 1.0f); @@ -1314,8 +1314,8 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int /* dot product and reflectivity */ /* inp = dotproduct, is = shader result, i = lamp energy (with shadow), i_noshad = i without shadow */ - inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; - + inp= dot_v3v3(vn, lv); + /* phong threshold to prevent backfacing faces having artefacts on ray shadow (terminator problem) */ /* this complex construction screams for a nicer implementation! (ton) */ if(R.r.mode & R_SHADOW) { @@ -1383,7 +1383,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int if(lar->shb || (lar->mode & LA_SHAD_RAY)) { if(vn==vnor) /* tangent trigger */ - lamp_get_shadow(lar, shi, INPR(shi->vn, lv), shadfac, shi->depth); + lamp_get_shadow(lar, shi, dot_v3v3(shi->vn, lv), shadfac, shi->depth); else lamp_get_shadow(lar, shi, inp, shadfac, shi->depth); @@ -1425,7 +1425,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int add_to_diffuse(shr->diff, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]); } else - VECCOPY(shr->diff, shr->shad); + copy_v3_v3(shr->diff, shr->shad); } } @@ -1531,7 +1531,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) continue; } - inpr= INPR(shi->vn, lv); + inpr= dot_v3v3(shi->vn, lv); if(inpr <= 0.0f) { if (shi->mat->shadowonly_flag == MA_SO_OLD) accum+= 1.0f; @@ -1712,9 +1712,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* AO was calculated for scanline already */ if(shi->depth || shi->volume_depth) ambient_occlusion(shi); - VECCOPY(shr->ao, shi->ao); - VECCOPY(shr->env, shi->env); // XXX multiply - VECCOPY(shr->indirect, shi->indirect); // XXX multiply + copy_v3_v3(shr->ao, shi->ao); + copy_v3_v3(shr->env, shi->env); // XXX multiply + copy_v3_v3(shr->indirect, shi->indirect); // XXX multiply } } } @@ -1759,7 +1759,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) invalpha= (shr->col[3] > FLT_EPSILON)? 1.0f/shr->col[3]: 1.0f; if(texfac==0.0f) { - VECCOPY(col, shr->col); + copy_v3_v3(col, shr->col); mul_v3_fl(col, invalpha); } else if(texfac==1.0f) { @@ -1767,7 +1767,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) mul_v3_fl(col, invalpha); } else { - VECCOPY(col, shr->col); + copy_v3_v3(col, shr->col); mul_v3_fl(col, invalpha); col[0]= pow(col[0], 1.0f-texfac); col[1]= pow(col[1], 1.0f-texfac); @@ -1787,9 +1787,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } if(shi->combinedflag & SCE_PASS_SHADOW) - VECCOPY(shr->combined, shr->shad) /* note, no ';' ! */ + copy_v3_v3(shr->combined, shr->shad); /* note, no ';' ! */ else - VECCOPY(shr->combined, shr->diff); + copy_v3_v3(shr->combined, shr->diff); /* calculate shadow pass, we use a multiplication mask */ /* if diff = 0,0,0 it doesn't matter what the shadow pass is, so leave it as is */ @@ -1864,10 +1864,10 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) result[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->combined[2]; if(passflag & SCE_PASS_REFLECT) - VECSUB(shr->refl, result, shr->combined); + sub_v3_v3v3(shr->refl, result, shr->combined); if(shi->combinedflag & SCE_PASS_REFLECT) - VECCOPY(shr->combined, result); + copy_v3_v3(shr->combined, result); } diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 0ba13b31c4b..36b577ce9a4 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -394,8 +394,8 @@ static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int for(i=0; i<node->totpoint; i++) { ScatterPoint *p= &node->points[i]; - VECSUB(sub, co, p->co); - dist= INPR(sub, sub); + sub_v3_v3v3(sub, co, p->co); + dist= dot_v3v3(sub, sub); if(p->back) add_radiance(tree, NULL, p->rad, 0.0f, p->area, dist, result); @@ -418,8 +418,8 @@ static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int } else { /* decide subnode traversal based on maximum solid angle */ - VECSUB(sub, co, subnode->co); - dist= INPR(sub, sub); + sub_v3_v3v3(sub, co, subnode->co); + dist= dot_v3v3(sub, sub); /* actually area/dist > error, but this avoids division */ if(subnode->area+subnode->backarea>tree->error*dist) { diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 2037acc943f..18132c4a7f3 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -490,7 +490,7 @@ static void *vol_precache_part(void *data) RayObject *tree = pa->tree; ShadeInput *shi = pa->shi; float scatter_col[3] = {0.f, 0.f, 0.f}; - float co[3], cco[3]; + float co[3], cco[3], view[3]; int x, y, z, i; int res[3]; @@ -523,9 +523,9 @@ static void *vol_precache_part(void *data) continue; } - copy_v3_v3(shi->view, cco); - normalize_v3(shi->view); - vol_get_scattering(shi, scatter_col, cco); + copy_v3_v3(view, cco); + normalize_v3(view); + vol_get_scattering(shi, scatter_col, cco, view); obi->volume_precache->data_r[i] = scatter_col[0]; obi->volume_precache->data_g[i] = scatter_col[1]; diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 19bbb11e143..ad6a951adff 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -70,13 +70,13 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* luminance rec. 709 */ -BM_INLINE float luminance(float* col) +BM_INLINE float luminance(const float col[3]) { return (0.212671f*col[0] + 0.71516f*col[1] + 0.072169f*col[2]); } /* tracing */ -static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co) +static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3]) { float visibility = 1.f; @@ -95,7 +95,7 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co) is.dir[2] = -lar->vec[2]; is.dist = R.maxdist; } else { - VECSUB( is.dir, lar->co, is.start ); + sub_v3_v3v3(is.dir, lar->co, is.start); is.dist = normalize_v3( is.dir ); } @@ -121,11 +121,11 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co) return visibility; } -static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type) +static int vol_get_bounds(ShadeInput *shi, const float co[3], const float vec[3], float hitco[3], Isect *isect, int intersect_type) { - VECCOPY(isect->start, co); - VECCOPY(isect->dir, vec ); + copy_v3_v3(isect->start, co); + copy_v3_v3(isect->dir, vec); isect->dist = FLT_MAX; isect->mode= RE_RAY_MIRROR; isect->last_hit = NULL; @@ -153,7 +153,7 @@ static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, } } -static void shade_intersection(ShadeInput *shi, float *col, Isect *is) +static void shade_intersection(ShadeInput *shi, float col_r[4], Isect *is) { ShadeInput shi_new; ShadeResult shr_new; @@ -173,7 +173,7 @@ static void shade_intersection(ShadeInput *shi, float *col, Isect *is) shi_new.light_override= shi->light_override; shi_new.mat_override= shi->mat_override; - VECCOPY(shi_new.camera_co, is->start); + copy_v3_v3(shi_new.camera_co, is->start); memset(&shr_new, 0, sizeof(ShadeResult)); @@ -182,16 +182,16 @@ static void shade_intersection(ShadeInput *shi, float *col, Isect *is) shade_ray(is, &shi_new, &shr_new); } - copy_v3_v3(col, shr_new.combined); - col[3] = shr_new.alpha; + copy_v3_v3(col_r, shr_new.combined); + col_r[3] = shr_new.alpha; } -static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *col) +static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, const float co[3], float col[3]) { Isect isect; - VECCOPY(isect.start, co); - VECCOPY(isect.dir, shi->view); + copy_v3_v3(isect.start, co); + copy_v3_v3(isect.dir, shi->view); isect.dist = FLT_MAX; isect.mode= RE_RAY_MIRROR; @@ -213,7 +213,7 @@ static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *co /* trilinear interpolation */ -static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float *scatter_col, float *co) +static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float scatter_col[3], const float co[3]) { VolumePrecache *vp = shi->obi->volume_precache; float bbmin[3], bbmax[3], dim[3]; @@ -238,7 +238,7 @@ static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float *sca /* Meta object density, brute force for now * (might be good enough anyway, don't need huge number of metaobs to model volumetric objects */ -static float metadensity(Object* ob, float* co) +static float metadensity(Object* ob, const float co[3]) { float mat[4][4], imat[4][4], dens = 0.f; MetaBall* mb = (MetaBall*)ob->data; @@ -284,7 +284,7 @@ static float metadensity(Object* ob, float* co) return (dens < 0.f) ? 0.f : dens; } -float vol_get_density(struct ShadeInput *shi, float *co) +float vol_get_density(struct ShadeInput *shi, const float co[3]) { float density = shi->mat->vol.density; float density_scale = shi->mat->vol.density_scale; @@ -305,11 +305,11 @@ float vol_get_density(struct ShadeInput *shi, float *co) /* Color of light that gets scattered out by the volume */ /* Uses same physically based scattering parameter as in transmission calculations, * along with artificial reflection scale/reflection color tint */ -static void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co) +static void vol_get_reflection_color(ShadeInput *shi, float ref_col[3], const float co[3]) { float scatter = shi->mat->vol.scattering; float reflection= shi->mat->vol.reflection; - VECCOPY(ref_col, shi->mat->vol.reflection_col); + copy_v3_v3(ref_col, shi->mat->vol.reflection_col); if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_REFLECTION_COL)) do_volume_tex(shi, co, MAP_SCATTERING+MAP_REFLECTION_COL, ref_col, &scatter); @@ -325,10 +325,10 @@ static void vol_get_reflection_color(ShadeInput *shi, float *ref_col, float *co) /* compute emission component, amount of radiance to add per segment * can be textured with 'emit' */ -static void vol_get_emission(ShadeInput *shi, float *emission_col, float *co) +static void vol_get_emission(ShadeInput *shi, float emission_col[3], const float co[3]) { float emission = shi->mat->vol.emission; - VECCOPY(emission_col, shi->mat->vol.emission_col); + copy_v3_v3(emission_col, shi->mat->vol.emission_col); if (shi->mat->mapto_textured & (MAP_EMISSION+MAP_EMISSION_COL)) do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission); @@ -343,7 +343,7 @@ static void vol_get_emission(ShadeInput *shi, float *emission_col, float *co) * This can possibly use a specific scattering color, * and absorption multiplier factor too, but these parameters are left out for simplicity. * It's easy enough to get a good wide range of results with just these two parameters. */ -static void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co) +static void vol_get_sigma_t(ShadeInput *shi, float sigma_t[3], const float co[3]) { /* technically absorption, but named transmission color * since it describes the effect of the coloring *after* absorption */ @@ -361,7 +361,7 @@ static void vol_get_sigma_t(ShadeInput *shi, float *sigma_t, float *co) /* phase function - determines in which directions the light * is scattered in the volume relative to incoming direction * and view direction */ -static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, float *w, float *wp) +static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, const float w[3], const float wp[3]) { const float normalize = 0.25f; // = 1.f/4.f = M_PI/(4.f*M_PI) @@ -408,7 +408,7 @@ static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, float *w, float } /* Compute transmittance = e^(-attenuation) */ -static void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float *co, float density) +static void vol_get_transmittance_seg(ShadeInput *shi, float tr[3], float stepsize, const float co[3], float density) { /* input density = density at co */ float tau[3] = {0.f, 0.f, 0.f}; @@ -428,7 +428,7 @@ static void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize } /* Compute transmittance = e^(-attenuation) */ -static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float *endco) +static void vol_get_transmittance(ShadeInput *shi, float tr[3], const float co[3], const float endco[3]) { float p[3] = {co[0], co[1], co[2]}; float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]}; @@ -464,7 +464,7 @@ static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float * tr[2] = expf(-tau[2]); } -static void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol) +static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const float view[3], LampRen *lar, float lacol[3]) { float visifac, lv[3], lampdist; float tr[3]={1.0,1.0,1.0}; @@ -487,7 +487,7 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, mul_v3_fl(lacol, visifac); if (ELEM(lar->type, LA_SUN, LA_HEMI)) - VECCOPY(lv, lar->vec); + copy_v3_v3(lv, lar->vec); negate_v3(lv); if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) { @@ -535,7 +535,7 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, if (luminance(lacol) < 0.001f) return; normalize_v3(lv); - p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, shi->view, lv); + p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, view, lv); /* physically based scattering with non-physically based RGB gain */ vol_get_reflection_color(shi, ref_col, co); @@ -546,14 +546,14 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, } /* single scattering only for now */ -void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co) +void vol_get_scattering(ShadeInput *shi, float scatter_col[3], const float co[3], const float view[3]) { ListBase *lights; GroupObject *go; LampRen *lar; - - scatter_col[0] = scatter_col[1] = scatter_col[2] = 0.f; - + + zero_v3(scatter_col); + lights= get_lights(shi); for(go=lights->first; go; go= go->next) { @@ -561,7 +561,7 @@ void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co) lar= go->lampren; if (lar) { - vol_shade_one_lamp(shi, co, lar, lacol); + vol_shade_one_lamp(shi, co, view, lar, lacol); add_v3_v3(scatter_col, lacol); } } @@ -585,7 +585,7 @@ outgoing radiance from behind surface * beam transmittance/attenuation * it also makes it harder to control the overall look of the volume since coloring the outscattered light results * in the inverse color being transmitted through the rest of the volume. */ -static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco) +static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co[3], const float endco[3]) { float radiance[3] = {0.f, 0.f, 0.f}; float tr[3] = {1.f, 1.f, 1.f}; @@ -629,7 +629,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float vol_get_precached_scattering(&R, shi, scatter_col, p2); } else - vol_get_scattering(shi, scatter_col, p); + vol_get_scattering(shi, scatter_col, p, shi->view); radiance[0] += stepd * tr[0] * (emit_col[0] + scatter_col[0]); radiance[1] += stepd * tr[1] * (emit_col[1] + scatter_col[1]); @@ -736,7 +736,7 @@ static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int in copy_v3_v3(shr->combined, col); shr->alpha = col[3]; - VECCOPY(shr->diff, shr->combined); + copy_v3_v3(shr->diff, shr->combined); } /* Traces a shadow through the object, diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 925f8529dfa..ba922620ee1 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -239,7 +239,7 @@ static short cliptestf(float p, float q, float *u1, float *u2) return 1; } -int testclip(float *v) +int testclip(const float v[3]) { float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/ short c=0; @@ -1692,7 +1692,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo /* ------------------------------------------------------------------------- */ -void projectverto(float *v1, float winmat[][4], float *adr) +void projectverto(const float v1[3], float winmat[][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x,y,z; @@ -1710,7 +1710,7 @@ void projectverto(float *v1, float winmat[][4], float *adr) /* ------------------------------------------------------------------------- */ -void projectvert(float *v1, float winmat[][4], float *adr) +void projectvert(const float v1[3], float winmat[][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x,y,z; diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 21a725124ad..29cbeb84058 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -256,7 +256,7 @@ static void wm_drop_operator_draw(char *name, int x, int y) glColor4ub(0, 0, 0, 50); - uiSetRoundBox(15+16); + uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA); uiRoundBox(x, y, x + width + 8, y + 15, 4); glColor4ub(255, 255, 255, 255); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 8861f128c4b..518ebeafc80 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -441,12 +441,17 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int pop if(op->reports->list.first) { /* FIXME, temp setting window, see other call to uiPupMenuReports for why */ wmWindow *win_prev= CTX_wm_window(C); + ScrArea *area_prev= CTX_wm_area(C); + ARegion *ar_prev= CTX_wm_region(C); + if(win_prev==NULL) CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); uiPupMenuReports(C, op->reports); CTX_wm_window_set(C, win_prev); + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, ar_prev); } } @@ -1394,6 +1399,9 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa * only have because lib linking errors need to be seen by users :( * it can be removed without breaking anything but then no linking errors - campbell */ wmWindow *win_prev= CTX_wm_window(C); + ScrArea *area_prev= CTX_wm_area(C); + ARegion *ar_prev= CTX_wm_region(C); + if(win_prev==NULL) CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); @@ -1405,6 +1413,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa BLI_movelisttolist(&CTX_wm_reports(C)->list, &handler->op->reports->list); CTX_wm_window_set(C, win_prev); + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, ar_prev); } WM_operator_free(handler->op); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 0e94ad72d35..854fa688ea4 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -47,6 +47,7 @@ #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_idprop.h" +#include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_screen.h" @@ -680,6 +681,17 @@ wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf, const char *idname, EnumPrope wmKeyMap *km= WM_keymap_find(keyconf, idname, 0, 0); km->flag |= KEYMAP_MODAL; km->modal_items= items; + + if(!items) { + /* init modal items from default config */ + wmWindowManager *wm = G.main->wm.first; + wmKeyMap *defaultkm= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0); + + if(defaultkm) { + km->modal_items = defaultkm->modal_items; + km->poll = defaultkm->poll; + } + } return km; } diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index ddfdfc97bdc..c8bf3b002f1 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -138,6 +138,7 @@ endif() bf_intern_ghost # duplicate for linking bf_blenkernel # duplicate for linking bf_intern_mikktspace + extern_recastnavigation ) if(WITH_MOD_CLOTH_ELTOPO) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index bf2808ba4c0..93236f93ceb 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -797,6 +797,7 @@ endif() bf_intern_smoke extern_minilzo extern_lzma + extern_recastnavigation ge_logic_ketsji ge_phys_common ge_logic @@ -818,6 +819,8 @@ endif() bf_blenfont bf_intern_audaspace bf_intern_mikktspace + extern_recastnavigation + bf_editor_util # --- BAD LEVEL CALL HERE --- XXX, this should be removed before release! ) if(WITH_MOD_CLOTH_ELTOPO) diff --git a/source/creator/creator.c b/source/creator/creator.c index 9b2cfb08382..264b4fc6208 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -542,22 +542,17 @@ static int set_output(int argc, const char **argv, void *data) static int set_engine(int argc, const char **argv, void *data) { bContext *C = data; - if (argc >= 1) - { - if (!strcmp(argv[1],"help")) - { + if (argc >= 2) { + if (!strcmp(argv[1], "help")) { RenderEngineType *type = NULL; - - for( type = R_engines.first; type; type = type->next ) - { + printf("Blender Engine Listing:\n"); + for( type = R_engines.first; type; type = type->next ) { printf("\t%s\n", type->idname); } exit(0); } - else - { - if (CTX_data_scene(C)==NULL) - { + else { + if (CTX_data_scene(C)==NULL) { printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n"); } else { @@ -574,7 +569,7 @@ static int set_engine(int argc, const char **argv, void *data) } else { - printf("\nEngine not specified.\n"); + printf("\nEngine not specified, give 'help' for a list of available engines.\n"); return 0; } } diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 810e9b6ddfb..ce542671425 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -169,6 +169,11 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c int disableVBO = (U.gameflags & USER_DISABLE_VBO); U.gameflags |= USER_DISABLE_VBO; + // Globals to be carried on over blender files + GlobalSettings gs; + gs.matmode= startscene->gm.matmode; + gs.glslflag= startscene->gm.flag; + do { View3D *v3d= CTX_wm_view3d(C); @@ -239,6 +244,9 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); + //set the global settings (carried over if restart/load new files) + ketsjiengine->SetGlobalSettings(&gs); + #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #endif @@ -370,12 +378,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c if(GPU_glsl_support()) useglslmat = true; - else if(scene->gm.matmode == GAME_MAT_GLSL) + else if(gs.matmode == GAME_MAT_GLSL) usemat = false; - if(usemat && (scene->gm.matmode != GAME_MAT_TEXFACE)) + if(usemat && (gs.matmode != GAME_MAT_TEXFACE)) sceneconverter->SetMaterials(true); - if(useglslmat && (scene->gm.matmode == GAME_MAT_GLSL)) + if(useglslmat && (gs.matmode == GAME_MAT_GLSL)) sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(keyboarddevice, @@ -494,6 +502,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c } printf("Blender Game Engine Finished\n"); exitstring = ketsjiengine->GetExitString(); + gs = *(ketsjiengine->GetGlobalSettings()); // when exiting the mainloop diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index fcfc07e631e..d4b43cd7ac1 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -180,6 +180,9 @@ extern Material defmaterial; /* material.c */ #include "BL_ArmatureObject.h" #include "BL_DeformableGameObject.h" +#include "KX_NavMeshObject.h" +#include "KX_ObstacleSimulation.h" + #ifdef __cplusplus extern "C" { #endif @@ -1741,7 +1744,14 @@ static KX_GameObject *gameobject_from_blenderobject( // needed for python scripting kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); - + + if (ob->gameflag & OB_NAVMESH) + { + gameobj = new KX_NavMeshObject(kxscene,KX_Scene::m_callbacks); + gameobj->AddMesh(meshobj); + break; + } + gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks); // set transformation @@ -2710,6 +2720,46 @@ void BL_ConvertBlenderObjects(struct Main* maggie, converter->RegisterWorldInfo(worldinfo); kxscene->SetWorldInfo(worldinfo); + //create object representations for obstacle simulation + KX_ObstacleSimulation* obssimulation = kxscene->GetObstacleSimulation(); + if (obssimulation) + { + for ( i=0;i<objectlist->GetCount();i++) + { + KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); + struct Object* blenderobject = gameobj->GetBlenderObject(); + if (blenderobject->gameflag & OB_HASOBSTACLE) + { + obssimulation->AddObstacleForObj(gameobj); + } + } + } + + //process navigation mesh objects + for ( i=0; i<objectlist->GetCount();i++) + { + KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); + struct Object* blenderobject = gameobj->GetBlenderObject(); + if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH)) + { + KX_NavMeshObject* navmesh = static_cast<KX_NavMeshObject*>(gameobj); + navmesh->SetVisible(0, true); + navmesh->BuildNavMesh(); + if (obssimulation) + obssimulation->AddObstaclesForNavMesh(navmesh); + } + } + for ( i=0; i<inactivelist->GetCount();i++) + { + KX_GameObject* gameobj = static_cast<KX_GameObject*>(inactivelist->GetValue(i)); + struct Object* blenderobject = gameobj->GetBlenderObject(); + if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH)) + { + KX_NavMeshObject* navmesh = static_cast<KX_NavMeshObject*>(gameobj); + navmesh->SetVisible(0, true); + } + } + #define CONVERT_LOGIC #ifdef CONVERT_LOGIC // convert logic bricks, sensors, controllers and actuators diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 98afcf877a1..93c65eb38de 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -316,8 +316,8 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied) /* duplicate */ for (int v =0; v<m_bmesh->totvert; v++) { - VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); - VECCOPY(m_transnors[v], m_bmesh->mvert[v].no); + copy_v3_v3(m_transverts[v], m_bmesh->mvert[v].co); + normal_short_to_float_v3(m_transnors[v], m_bmesh->mvert[v].no); } } diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index 3a217ce9d74..039f454e870 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -56,6 +56,7 @@ set(INC ../../../intern/guardedalloc ../../../intern/moto/include ../../../intern/string + ../../../extern/recastnavigation/Detour/Include ) set(INC_SYS diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 6ba178cbb2f..a14e5fb5449 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -72,6 +72,7 @@ #include "KX_SCA_ReplaceMeshActuator.h" #include "KX_ParentActuator.h" #include "KX_SCA_DynamicActuator.h" +#include "KX_SteeringActuator.h" #include "KX_Scene.h" #include "KX_KetsjiEngine.h" @@ -100,6 +101,7 @@ #include "BL_ActionActuator.h" #include "BL_ShapeActionActuator.h" #include "BL_ArmatureActuator.h" +#include "RNA_access.h" #include "BL_Action.h" /* end of blender include block */ @@ -1064,6 +1066,45 @@ void BL_ConvertActuators(char* maggiename, baseact = tmparmact; break; } + case ACT_STEERING: + { + bSteeringActuator *stAct = (bSteeringActuator *) bact->data; + KX_GameObject *navmeshob = NULL; + if (stAct->navmesh) + { + PointerRNA settings_ptr; + RNA_pointer_create((ID *)stAct->navmesh, &RNA_GameObjectSettings, stAct->navmesh, &settings_ptr); + if (RNA_enum_get(&settings_ptr, "physics_type") == OB_BODY_TYPE_NAVMESH) + navmeshob = converter->FindGameObject(stAct->navmesh); + } + KX_GameObject *targetob = converter->FindGameObject(stAct->target); + + int mode = KX_SteeringActuator::KX_STEERING_NODEF; + switch(stAct->type) + { + case ACT_STEERING_SEEK: + mode = KX_SteeringActuator::KX_STEERING_SEEK; + break; + case ACT_STEERING_FLEE: + mode = KX_SteeringActuator::KX_STEERING_FLEE; + break; + case ACT_STEERING_PATHFOLLOWING: + mode = KX_SteeringActuator::KX_STEERING_PATHFOLLOWING; + break; + } + + bool selfTerminated = (stAct->flag & ACT_STEERING_SELFTERMINATED) !=0; + bool enableVisualization = (stAct->flag & ACT_STEERING_ENABLEVISUALIZATION) !=0; + short facingMode = (stAct->flag & ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0; + bool normalup = (stAct->flag & ACT_STEERING_NORMALUP) !=0; + KX_SteeringActuator *tmpstact + = new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist, + stAct->velocity, stAct->acceleration, stAct->turnspeed, + selfTerminated, stAct->updateTime, + scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization); + baseact = tmpstact; + break; + } default: ; /* generate some error */ } diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 0ae22d548c5..e155677e522 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -20,6 +20,7 @@ incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu' incs += ' #source/blender/windowmanager' incs += ' #source/blender/makesrna' incs += ' #source/blender/ikplugin' +incs += ' #extern/recastnavigation/Detour/Include' incs += ' #extern/Eigen2' incs += ' ' + env['BF_BULLET_INC'] diff --git a/source/gameengine/Expressions/IfExpr.h b/source/gameengine/Expressions/IfExpr.h index 5ac8d835afd..e67134c2271 100644 --- a/source/gameengine/Expressions/IfExpr.h +++ b/source/gameengine/Expressions/IfExpr.h @@ -20,7 +20,7 @@ #if !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_) #define AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_ -#if _MSC_VER >= 1000 +#if defined(_MSC_VER) && _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index bfcec983e2a..d2a8de32895 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -90,6 +90,7 @@ public: KX_ACT_SHAPEACTION, KX_ACT_STATE, KX_ACT_ARMATURE, + KX_ACT_STEERING, }; SCA_IActuator(SCA_IObject* gameobj, KX_ACTUATOR_TYPE type); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 5bc6093a9ff..7b47d74d424 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -151,7 +151,7 @@ GPG_Application::~GPG_Application(void) -bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene, int argc, char **argv) +bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene, GlobalSettings *gs, int argc, char **argv) { bool result = false; @@ -168,6 +168,9 @@ bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene, int a m_argc= argc; m_argv= argv; + /* Global Settings */ + m_globalSettings= gs; + return result; } @@ -511,6 +514,12 @@ int GPG_Application::getExitRequested(void) } +GlobalSettings* GPG_Application::getGlobalSettings(void) +{ + return m_ketsjiengine->GetGlobalSettings(); +} + + const STR_String& GPG_Application::getExitString(void) { @@ -552,7 +561,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) if(GPU_glsl_support()) m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0); - else if(gm->matmode == GAME_MAT_GLSL) + else if(m_globalSettings->matmode == GAME_MAT_GLSL) m_blendermat = false; // create the canvas, rasterizer and rendertools @@ -629,6 +638,9 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties); m_ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); + //set the global settings (carried over if restart/load new files) + m_ketsjiengine->SetGlobalSettings(m_globalSettings); + m_engineInitialized = true; } @@ -685,9 +697,9 @@ bool GPG_Application::startEngine(void) // if (always_use_expand_framing) // sceneconverter->SetAlwaysUseExpandFraming(true); - if(m_blendermat && (m_startScene->gm.matmode != GAME_MAT_TEXFACE)) + if(m_blendermat && (m_globalSettings->matmode != GAME_MAT_TEXFACE)) m_sceneconverter->SetMaterials(true); - if(m_blenderglslmat && (m_startScene->gm.matmode == GAME_MAT_GLSL)) + if(m_blenderglslmat && (m_globalSettings->matmode == GAME_MAT_GLSL)) m_sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(m_keyboard, diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index c0638517657..df87aea1195 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -39,6 +39,8 @@ #include <wtypes.h> #endif +#include "KX_KetsjiEngine.h" + class KX_KetsjiEngine; class KX_ISceneConverter; class NG_LoopBackNetworkDeviceInterface; @@ -61,7 +63,7 @@ public: GPG_Application(GHOST_ISystem* system); ~GPG_Application(void); - bool SetGameEngineData(struct Main* maggie, struct Scene* scene, int argc, char** argv); + bool SetGameEngineData(struct Main* maggie, struct Scene* scene, GlobalSettings* gs, int argc, char** argv); bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0); bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0); @@ -74,6 +76,7 @@ public: virtual bool processEvent(GHOST_IEvent* event); int getExitRequested(void); const STR_String& getExitString(void); + GlobalSettings* getGlobalSettings(void); bool StartGameEngine(int stereoMode); void StopGameEngine(); @@ -111,6 +114,8 @@ protected: /* Exit state. */ int m_exitRequested; STR_String m_exitString; + GlobalSettings* m_globalSettings; + /* GHOST system abstraction. */ GHOST_ISystem* m_system; /* Main window. */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 3f8bcf9e2ad..d4ce19de83f 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -746,6 +746,11 @@ int main(int argc, char** argv) if(filename[0]) BLI_path_cwd(filename); + + // fill the GlobalSettings with the first scene files + // those may change during the game and persist after using Game Actuator + GlobalSettings gs; + do { // Read the Blender file @@ -799,9 +804,13 @@ int main(int argc, char** argv) Scene *scene = bfd->curscene; G.main = maggie; - if (firstTimeRunning) + if (firstTimeRunning) { G.fileflags = bfd->fileflags; + gs.matmode= scene->gm.matmode; + gs.glslflag= scene->gm.flag; + } + //Seg Fault; icon.c gIcons == 0 BKE_icons_init(1); @@ -861,7 +870,7 @@ int main(int argc, char** argv) } // GPG_Application app (system, maggie, startscenename); - app.SetGameEngineData(maggie, scene, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */ + app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */ BLI_strncpy(pathname, maggie->name, sizeof(pathname)); if(G.main != maggie) { BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name)); @@ -957,6 +966,7 @@ int main(int argc, char** argv) { run = false; exitstring = app.getExitString(); + gs = *app.getGlobalSettings(); } } app.StopGameEngine(); diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index 99c9fb25a65..9d8b1781869 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -57,6 +57,8 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_PATH} + ../../../extern/recastnavigation/Recast/Include + ../../../extern/recastnavigation/Detour/Include ) set(SRC @@ -90,9 +92,11 @@ set(SRC KX_MeshProxy.cpp KX_MotionState.cpp KX_MouseFocusSensor.cpp + KX_NavMeshObject.cpp KX_NearSensor.cpp KX_ObColorIpoSGController.cpp KX_ObjectActuator.cpp + KX_ObstacleSimulation.cpp KX_OrientationInterpolator.cpp KX_ParentActuator.cpp KX_PhysicsObjectWrapper.cpp @@ -120,6 +124,7 @@ set(SRC KX_SceneActuator.cpp KX_SoundActuator.cpp KX_StateActuator.cpp + KX_SteeringActuator.cpp KX_TimeCategoryLogger.cpp KX_TimeLogger.cpp KX_TouchEventManager.cpp @@ -167,9 +172,11 @@ set(SRC KX_MeshProxy.h KX_MotionState.h KX_MouseFocusSensor.h + KX_NavMeshObject.h KX_NearSensor.h KX_ObColorIpoSGController.h KX_ObjectActuator.h + KX_ObstacleSimulation.h KX_OrientationInterpolator.h KX_ParentActuator.h KX_PhysicsEngineEnums.h @@ -199,6 +206,7 @@ set(SRC KX_SceneActuator.h KX_SoundActuator.h KX_StateActuator.h + KX_SteeringActuator.h KX_TimeCategoryLogger.h KX_TimeLogger.h KX_TouchEventManager.h diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 6adaea2d6ad..ae8d7094015 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -73,6 +73,7 @@ typedef unsigned long uint_ptr; #include "SCA_ISensor.h" #include "SCA_IController.h" #include "NG_NetworkScene.h" //Needed for sendMessage() +#include "KX_ObstacleSimulation.h" #include "BL_ActionManager.h" @@ -110,7 +111,8 @@ KX_GameObject::KX_GameObject( m_xray(false), m_pHitObject(NULL), m_actionManager(NULL), - m_isDeformable(false) + m_isDeformable(false), + m_pObstacleSimulation(NULL) #ifdef WITH_PYTHON , m_attr_dict(NULL) #endif @@ -157,6 +159,12 @@ KX_GameObject::~KX_GameObject() { delete m_pGraphicController; } + + if (m_pObstacleSimulation) + { + m_pObstacleSimulation->DestroyObstacleForObj(this); + } + if (m_actionManager) { KX_GetActiveScene()->RemoveAnimatedObject(this); @@ -428,6 +436,14 @@ void KX_GameObject::ProcessReplica() m_actionManager = new BL_ActionManager(this); m_state = 0; + KX_Scene* scene = KX_GetActiveScene(); + KX_ObstacleSimulation* obssimulation = scene->GetObstacleSimulation(); + struct Object* blenderobject = GetBlenderObject(); + if (obssimulation && (blenderobject->gameflag & OB_HASOBSTACLE)) + { + obssimulation->AddObstacleForObj(this); + } + #ifdef WITH_PYTHON if(m_attr_dict) m_attr_dict= PyDict_Copy(m_attr_dict); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 6e79914172b..655bc9ff080 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -65,6 +65,7 @@ class PHY_IGraphicController; class PHY_IPhysicsEnvironment; class BL_ActionManager; struct Object; +class KX_ObstacleSimulation; struct bAction; #ifdef WITH_PYTHON @@ -115,6 +116,9 @@ protected: MT_CmMatrix4x4 m_OpenGL_4x4Matrix; + KX_ObstacleSimulation* m_pObstacleSimulation; + + // The action manager is used to play/stop/update actions BL_ActionManager* m_actionManager; @@ -864,6 +868,16 @@ public: } m_bSuspendDynamics = false; } + + void RegisterObstacle(KX_ObstacleSimulation* obstacleSimulation) + { + m_pObstacleSimulation = obstacleSimulation; + } + + void UnregisterObstacle() + { + m_pObstacleSimulation = NULL; + } KX_ClientObjectInfo* getClientInfo() { return m_pClient_info; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index ca67333166c..65ff06456b4 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -84,6 +84,8 @@ #include "DNA_world_types.h" #include "DNA_scene_types.h" +#include "KX_NavMeshObject.h" + // If define: little test for Nzc: guarded drawing. If the canvas is // not valid, skip rendering this frame. //#define NZC_GUARDED_OUTPUT @@ -1343,7 +1345,7 @@ void KX_KetsjiEngine::PostRenderScene(KX_Scene* scene) #ifdef WITH_PYTHON scene->RunDrawingCallbacks(scene->GetPostDrawCB()); #endif - m_rasterizer->FlushDebugLines(); + m_rasterizer->FlushDebugShapes(); } void KX_KetsjiEngine::StopEngine() @@ -1934,4 +1936,14 @@ void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const b = m_overrideFrameColorB; } +void KX_KetsjiEngine::SetGlobalSettings(GlobalSettings* gs) +{ + m_globalsettings.matmode = gs->matmode; + m_globalsettings.glslflag = gs->glslflag; +} + +GlobalSettings* KX_KetsjiEngine::GetGlobalSettings(void) +{ + return &m_globalsettings; +} diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index b1009c7d8f0..f2f978a0afa 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -62,6 +62,11 @@ enum KX_ExitRequestMode KX_EXIT_REQUEST_MAX }; +typedef struct { + short matmode; + short glslflag; +} GlobalSettings; + /** * KX_KetsjiEngine is the core game engine class. */ @@ -193,6 +198,9 @@ private: /** Blue component of framing bar color. */ float m_overrideFrameColorB; + /** Settings that doesn't go away with Game Actuator */ + GlobalSettings m_globalsettings; + void RenderFrame(KX_Scene* scene, KX_Camera* cam); void PostRenderScene(KX_Scene* scene); void RenderDebugProperties(); @@ -404,7 +412,10 @@ public: KX_Scene* CreateScene(const STR_String& scenename); KX_Scene* CreateScene(Scene *scene); - + + GlobalSettings* GetGlobalSettings(void); + void SetGlobalSettings(GlobalSettings* gs); + protected: /** * Processes all scheduled scene activity. diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp new file mode 100644 index 00000000000..f72c98fb4bf --- /dev/null +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -0,0 +1,709 @@ +/** +* $Id$ +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#include "BLI_math_vector.h" +#include "KX_NavMeshObject.h" +#include "RAS_MeshObject.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +extern "C" { +#include "BKE_scene.h" +#include "BKE_customdata.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_DerivedMesh.h" +#include "BKE_navmesh_conversion.h" +} + +#include "KX_PythonInit.h" +#include "KX_PyMath.h" +#include "Value.h" +#include "Recast.h" +#include "DetourStatNavMeshBuilder.h" +#include "KX_ObstacleSimulation.h" + +static const int MAX_PATH_LEN = 256; +static const float polyPickExt[3] = {2, 4, 2}; + +static void calcMeshBounds(const float* vert, int nverts, float* bmin, float* bmax) +{ + bmin[0] = bmax[0] = vert[0]; + bmin[1] = bmax[1] = vert[1]; + bmin[2] = bmax[2] = vert[2]; + for (int i=1; i<nverts; i++) + { + if (bmin[0]>vert[3*i+0]) bmin[0] = vert[3*i+0]; + if (bmin[1]>vert[3*i+1]) bmin[1] = vert[3*i+1]; + if (bmin[2]>vert[3*i+2]) bmin[2] = vert[3*i+2]; + + if (bmax[0]<vert[3*i+0]) bmax[0] = vert[3*i+0]; + if (bmax[1]<vert[3*i+1]) bmax[1] = vert[3*i+1]; + if (bmax[2]<vert[3*i+2]) bmax[2] = vert[3*i+2]; + } +} + +inline void flipAxes(float* vec) +{ + std::swap(vec[1],vec[2]); +} +KX_NavMeshObject::KX_NavMeshObject(void* sgReplicationInfo, SG_Callbacks callbacks) +: KX_GameObject(sgReplicationInfo, callbacks) +, m_navMesh(NULL) +{ + +} + +KX_NavMeshObject::~KX_NavMeshObject() +{ + if (m_navMesh) + delete m_navMesh; +} + +CValue* KX_NavMeshObject::GetReplica() +{ + KX_NavMeshObject* replica = new KX_NavMeshObject(*this); + replica->ProcessReplica(); + return replica; +} + +void KX_NavMeshObject::ProcessReplica() +{ + KX_GameObject::ProcessReplica(); + + BuildNavMesh(); + KX_Scene* scene = KX_GetActiveScene(); + KX_ObstacleSimulation* obssimulation = scene->GetObstacleSimulation(); + if (obssimulation) + obssimulation->AddObstaclesForNavMesh(this); + +} + +bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, + unsigned short* &polys, int& npolys, unsigned short *&dmeshes, + float *&dvertices, int &ndvertsuniq, unsigned short *&dtris, + int& ndtris, int &vertsPerPoly) +{ + DerivedMesh* dm = mesh_create_derived_no_virtual(KX_GetActiveScene()->GetBlenderScene(), GetBlenderObject(), + NULL, CD_MASK_MESH); + int* recastData = (int*) dm->getFaceDataArray(dm, CD_RECAST); + if (recastData) + { + int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL; + int nAllVerts = 0; + float *allVerts = NULL; + buildNavMeshDataByDerivedMesh(dm, vertsPerPoly, nAllVerts, allVerts, ndtris, dtris, + npolys, dmeshes, polys, dtrisToPolysMap, dtrisToTrisMap, trisToFacesMap); + + unsigned short *verticesMap = new unsigned short[nAllVerts]; + memset(verticesMap, 0xffff, sizeof(unsigned short)*nAllVerts); + int curIdx = 0; + //vertices - mesh verts + //iterate over all polys and create map for their vertices first... + for (int polyidx=0; polyidx<npolys; polyidx++) + { + unsigned short* poly = &polys[polyidx*vertsPerPoly*2]; + for (int i=0; i<vertsPerPoly; i++) + { + unsigned short idx = poly[i]; + if (idx==0xffff) + break; + if (verticesMap[idx]==0xffff) + { + verticesMap[idx] = curIdx++; + } + poly[i] = verticesMap[idx]; + } + } + nverts = curIdx; + //...then iterate over detailed meshes + //transform indices to local ones (for each navigation polygon) + for (int polyidx=0; polyidx<npolys; polyidx++) + { + unsigned short *poly = &polys[polyidx*vertsPerPoly*2]; + int nv = polyNumVerts(poly, vertsPerPoly); + unsigned short *dmesh = &dmeshes[4*polyidx]; + unsigned short tribase = dmesh[2]; + unsigned short trinum = dmesh[3]; + unsigned short vbase = curIdx; + for (int j=0; j<trinum; j++) + { + unsigned short* dtri = &dtris[(tribase+j)*3*2]; + for (int k=0; k<3; k++) + { + int newVertexIdx = verticesMap[dtri[k]]; + if (newVertexIdx==0xffff) + { + newVertexIdx = curIdx++; + verticesMap[dtri[k]] = newVertexIdx; + } + + if (newVertexIdx<nverts) + { + //it's polygon vertex ("shared") + int idxInPoly = polyFindVertex(poly, vertsPerPoly, newVertexIdx); + if (idxInPoly==-1) + { + printf("Building NavMeshObject: Error! Can't find vertex in polygon\n"); + return false; + } + dtri[k] = idxInPoly; + } + else + { + dtri[k] = newVertexIdx - vbase + nv; + } + } + } + dmesh[0] = vbase-nverts; //verts base + dmesh[1] = curIdx-vbase; //verts num + } + + vertices = new float[nverts*3]; + ndvertsuniq = curIdx - nverts; + if (ndvertsuniq>0) + { + dvertices = new float[ndvertsuniq*3]; + } + for (int vi=0; vi<nAllVerts; vi++) + { + int newIdx = verticesMap[vi]; + if (newIdx!=0xffff) + { + if (newIdx<nverts) + { + //navigation mesh vertex + memcpy(vertices+3*newIdx, allVerts+3*vi, 3*sizeof(float)); + } + else + { + //detailed mesh vertex + memcpy(dvertices+3*(newIdx-nverts), allVerts+3*vi, 3*sizeof(float)); + } + } + } + } + else + { + //create from RAS_MeshObject (detailed mesh is fake) + RAS_MeshObject* meshobj = GetMesh(0); + vertsPerPoly = 3; + nverts = meshobj->m_sharedvertex_map.size(); + if (nverts >= 0xffff) + return false; + //calculate count of tris + int nmeshpolys = meshobj->NumPolygons(); + npolys = nmeshpolys; + for (int p=0; p<nmeshpolys; p++) + { + int vertcount = meshobj->GetPolygon(p)->VertexCount(); + npolys+=vertcount-3; + } + + //create verts + vertices = new float[nverts*3]; + float* vert = vertices; + for (int vi=0; vi<nverts; vi++) + { + const float* pos = !meshobj->m_sharedvertex_map[vi].empty() ? meshobj->GetVertexLocation(vi) : NULL; + if (pos) + copy_v3_v3(vert, pos); + else + { + memset(vert, 0, 3*sizeof(float)); //vertex isn't in any poly, set dummy zero coordinates + } + vert+=3; + } + + //create tris + polys = new unsigned short[npolys*3*2]; + memset(polys, 0xff, sizeof(unsigned short)*3*2*npolys); + unsigned short *poly = polys; + RAS_Polygon* raspoly; + for (int p=0; p<nmeshpolys; p++) + { + raspoly = meshobj->GetPolygon(p); + for (int v=0; v<raspoly->VertexCount()-2; v++) + { + poly[0]= raspoly->GetVertex(0)->getOrigIndex(); + for (size_t i=1; i<3; i++) + { + poly[i]= raspoly->GetVertex(v+i)->getOrigIndex(); + } + poly += 6; + } + } + dmeshes = NULL; + dvertices = NULL; + ndvertsuniq = 0; + dtris = NULL; + ndtris = npolys; + } + dm->release(dm); + + return true; +} + + +bool KX_NavMeshObject::BuildNavMesh() +{ + if (m_navMesh) + { + delete m_navMesh; + m_navMesh = NULL; + } + + if (GetMeshCount()==0) + { + printf("Can't find mesh for navmesh object: %s \n", m_name.ReadPtr()); + return false; + } + + float *vertices = NULL, *dvertices = NULL; + unsigned short *polys = NULL, *dtris = NULL, *dmeshes = NULL; + int nverts = 0, npolys = 0, ndvertsuniq = 0, ndtris = 0; + int vertsPerPoly = 0; + if (!BuildVertIndArrays(vertices, nverts, polys, npolys, + dmeshes, dvertices, ndvertsuniq, dtris, ndtris, vertsPerPoly ) + || vertsPerPoly<3) + { + printf("Can't build navigation mesh data for object:%s \n", m_name.ReadPtr()); + return false; + } + + MT_Point3 pos; + if (dmeshes==NULL) + { + for (int i=0; i<nverts; i++) + { + flipAxes(&vertices[i*3]); + } + for (int i=0; i<ndvertsuniq; i++) + { + flipAxes(&dvertices[i*3]); + } + } + + buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly); + + float cs = 0.2f; + + if (!nverts || !npolys) + return false; + + float bmin[3], bmax[3]; + calcMeshBounds(vertices, nverts, bmin, bmax); + //quantize vertex pos + unsigned short* vertsi = new unsigned short[3*nverts]; + float ics = 1.f/cs; + for (int i=0; i<nverts; i++) + { + vertsi[3*i+0] = static_cast<unsigned short>((vertices[3*i+0]-bmin[0])*ics); + vertsi[3*i+1] = static_cast<unsigned short>((vertices[3*i+1]-bmin[1])*ics); + vertsi[3*i+2] = static_cast<unsigned short>((vertices[3*i+2]-bmin[2])*ics); + } + + // Calculate data size + const int headerSize = sizeof(dtStatNavMeshHeader); + const int vertsSize = sizeof(float)*3*nverts; + const int polysSize = sizeof(dtStatPoly)*npolys; + const int nodesSize = sizeof(dtStatBVNode)*npolys*2; + const int detailMeshesSize = sizeof(dtStatPolyDetail)*npolys; + const int detailVertsSize = sizeof(float)*3*ndvertsuniq; + const int detailTrisSize = sizeof(unsigned char)*4*ndtris; + + const int dataSize = headerSize + vertsSize + polysSize + nodesSize + + detailMeshesSize + detailVertsSize + detailTrisSize; + unsigned char* data = new unsigned char[dataSize]; + if (!data) + return false; + memset(data, 0, dataSize); + + unsigned char* d = data; + dtStatNavMeshHeader* header = (dtStatNavMeshHeader*)d; d += headerSize; + float* navVerts = (float*)d; d += vertsSize; + dtStatPoly* navPolys = (dtStatPoly*)d; d += polysSize; + dtStatBVNode* navNodes = (dtStatBVNode*)d; d += nodesSize; + dtStatPolyDetail* navDMeshes = (dtStatPolyDetail*)d; d += detailMeshesSize; + float* navDVerts = (float*)d; d += detailVertsSize; + unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize; + + // Store header + header->magic = DT_STAT_NAVMESH_MAGIC; + header->version = DT_STAT_NAVMESH_VERSION; + header->npolys = npolys; + header->nverts = nverts; + header->cs = cs; + header->bmin[0] = bmin[0]; + header->bmin[1] = bmin[1]; + header->bmin[2] = bmin[2]; + header->bmax[0] = bmax[0]; + header->bmax[1] = bmax[1]; + header->bmax[2] = bmax[2]; + header->ndmeshes = npolys; + header->ndverts = ndvertsuniq; + header->ndtris = ndtris; + + // Store vertices + for (int i = 0; i < nverts; ++i) + { + const unsigned short* iv = &vertsi[i*3]; + float* v = &navVerts[i*3]; + v[0] = bmin[0] + iv[0] * cs; + v[1] = bmin[1] + iv[1] * cs; + v[2] = bmin[2] + iv[2] * cs; + } + //memcpy(navVerts, vertices, nverts*3*sizeof(float)); + + // Store polygons + const unsigned short* src = polys; + for (int i = 0; i < npolys; ++i) + { + dtStatPoly* p = &navPolys[i]; + p->nv = 0; + for (int j = 0; j < vertsPerPoly; ++j) + { + if (src[j] == 0xffff) break; + p->v[j] = src[j]; + p->n[j] = src[vertsPerPoly+j]+1; + p->nv++; + } + src += vertsPerPoly*2; + } + + header->nnodes = createBVTree(vertsi, nverts, polys, npolys, vertsPerPoly, + cs, cs, npolys*2, navNodes); + + + if (dmeshes==NULL) + { + //create fake detail meshes + for (int i = 0; i < npolys; ++i) + { + dtStatPolyDetail& dtl = navDMeshes[i]; + dtl.vbase = 0; + dtl.nverts = 0; + dtl.tbase = i; + dtl.ntris = 1; + } + // setup triangles. + unsigned char* tri = navDTris; + for(size_t i=0; i<ndtris; i++) + { + for (size_t j=0; j<3; j++) + tri[4*i+j] = j; + } + } + else + { + //verts + memcpy(navDVerts, dvertices, ndvertsuniq*3*sizeof(float)); + //tris + unsigned char* tri = navDTris; + for(size_t i=0; i<ndtris; i++) + { + for (size_t j=0; j<3; j++) + tri[4*i+j] = dtris[6*i+j]; + } + //detailed meshes + for (int i = 0; i < npolys; ++i) + { + dtStatPolyDetail& dtl = navDMeshes[i]; + dtl.vbase = dmeshes[i*4+0]; + dtl.nverts = dmeshes[i*4+1]; + dtl.tbase = dmeshes[i*4+2]; + dtl.ntris = dmeshes[i*4+3]; + } + } + + m_navMesh = new dtStatNavMesh; + m_navMesh->init(data, dataSize, true); + + delete [] vertices; + delete [] polys; + if (dvertices) + { + delete [] dvertices; + } + + return true; +} + +dtStatNavMesh* KX_NavMeshObject::GetNavMesh() +{ + return m_navMesh; +} + +void KX_NavMeshObject::DrawNavMesh(NavMeshRenderMode renderMode) +{ + if (!m_navMesh) + return; + MT_Vector3 color(0.f, 0.f, 0.f); + + switch (renderMode) + { + case RM_POLYS : + case RM_WALLS : + for (int pi=0; pi<m_navMesh->getPolyCount(); pi++) + { + const dtStatPoly* poly = m_navMesh->getPoly(pi); + + for (int i = 0, j = (int)poly->nv-1; i < (int)poly->nv; j = i++) + { + if (poly->n[j] && renderMode==RM_WALLS) + continue; + const float* vif = m_navMesh->getVertex(poly->v[i]); + const float* vjf = m_navMesh->getVertex(poly->v[j]); + MT_Point3 vi(vif[0], vif[2], vif[1]); + MT_Point3 vj(vjf[0], vjf[2], vjf[1]); + vi = TransformToWorldCoords(vi); + vj = TransformToWorldCoords(vj); + KX_RasterizerDrawDebugLine(vi, vj, color); + } + } + break; + case RM_TRIS : + for (int i = 0; i < m_navMesh->getPolyDetailCount(); ++i) + { + const dtStatPoly* p = m_navMesh->getPoly(i); + const dtStatPolyDetail* pd = m_navMesh->getPolyDetail(i); + + for (int j = 0; j < pd->ntris; ++j) + { + const unsigned char* t = m_navMesh->getDetailTri(pd->tbase+j); + MT_Point3 tri[3]; + for (int k = 0; k < 3; ++k) + { + const float* v; + if (t[k] < p->nv) + v = m_navMesh->getVertex(p->v[t[k]]); + else + v = m_navMesh->getDetailVertex(pd->vbase+(t[k]-p->nv)); + float pos[3]; + vcopy(pos, v); + flipAxes(pos); + tri[k].setValue(pos); + } + + for (int k=0; k<3; k++) + tri[k] = TransformToWorldCoords(tri[k]); + + for (int k=0; k<3; k++) + KX_RasterizerDrawDebugLine(tri[k], tri[(k+1)%3], color); + } + } + break; + default: + /* pass */ + break; + } +} + +MT_Point3 KX_NavMeshObject::TransformToLocalCoords(const MT_Point3& wpos) +{ + MT_Matrix3x3 orientation = NodeGetWorldOrientation(); + const MT_Vector3& scaling = NodeGetWorldScaling(); + orientation.scale(scaling[0], scaling[1], scaling[2]); + MT_Transform worldtr(NodeGetWorldPosition(), orientation); + MT_Transform invworldtr; + invworldtr.invert(worldtr); + MT_Point3 lpos = invworldtr(wpos); + return lpos; +} + +MT_Point3 KX_NavMeshObject::TransformToWorldCoords(const MT_Point3& lpos) +{ + MT_Matrix3x3 orientation = NodeGetWorldOrientation(); + const MT_Vector3& scaling = NodeGetWorldScaling(); + orientation.scale(scaling[0], scaling[1], scaling[2]); + MT_Transform worldtr(NodeGetWorldPosition(), orientation); + MT_Point3 wpos = worldtr(lpos); + return wpos; +} + +int KX_NavMeshObject::FindPath(const MT_Point3& from, const MT_Point3& to, float* path, int maxPathLen) +{ + if (!m_navMesh) + return 0; + MT_Point3 localfrom = TransformToLocalCoords(from); + MT_Point3 localto = TransformToLocalCoords(to); + float spos[3], epos[3]; + localfrom.getValue(spos); flipAxes(spos); + localto.getValue(epos); flipAxes(epos); + dtStatPolyRef sPolyRef = m_navMesh->findNearestPoly(spos, polyPickExt); + dtStatPolyRef ePolyRef = m_navMesh->findNearestPoly(epos, polyPickExt); + + int pathLen = 0; + if (sPolyRef && ePolyRef) + { + dtStatPolyRef* polys = new dtStatPolyRef[maxPathLen]; + int npolys; + npolys = m_navMesh->findPath(sPolyRef, ePolyRef, spos, epos, polys, maxPathLen); + if (npolys) + { + pathLen = m_navMesh->findStraightPath(spos, epos, polys, npolys, path, maxPathLen); + for (int i=0; i<pathLen; i++) + { + flipAxes(&path[i*3]); + MT_Point3 waypoint(&path[i*3]); + waypoint = TransformToWorldCoords(waypoint); + waypoint.getValue(&path[i*3]); + } + } + } + + return pathLen; +} + +float KX_NavMeshObject::Raycast(const MT_Point3& from, const MT_Point3& to) +{ + if (!m_navMesh) + return 0.f; + MT_Point3 localfrom = TransformToLocalCoords(from); + MT_Point3 localto = TransformToLocalCoords(to); + float spos[3], epos[3]; + localfrom.getValue(spos); flipAxes(spos); + localto.getValue(epos); flipAxes(epos); + dtStatPolyRef sPolyRef = m_navMesh->findNearestPoly(spos, polyPickExt); + float t=0; + static dtStatPolyRef polys[MAX_PATH_LEN]; + m_navMesh->raycast(sPolyRef, spos, epos, t, polys, MAX_PATH_LEN); + return t; +} + +void KX_NavMeshObject::DrawPath(const float *path, int pathLen, const MT_Vector3& color) +{ + MT_Vector3 a,b; + for (int i=0; i<pathLen-1; i++) + { + a.setValue(&path[3*i]); + b.setValue(&path[3*(i+1)]); + KX_RasterizerDrawDebugLine(a, b, color); + } +} + + +#ifndef DISABLE_PYTHON +//---------------------------------------------------------------------------- +//Python + +PyTypeObject KX_NavMeshObject::Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "KX_NavMeshObject", + sizeof(PyObjectPlus_Proxy), + 0, + py_base_dealloc, + 0, + 0, + 0, + 0, + py_base_repr, + 0, + 0, + 0, + 0,0,0,0,0,0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &KX_GameObject::Type, + 0,0,0,0,0,0, + py_base_new +}; + +PyAttributeDef KX_NavMeshObject::Attributes[] = { + { NULL } //Sentinel +}; + +//KX_PYMETHODTABLE_NOARGS(KX_GameObject, getD), +PyMethodDef KX_NavMeshObject::Methods[] = { + KX_PYMETHODTABLE(KX_NavMeshObject, findPath), + KX_PYMETHODTABLE(KX_NavMeshObject, raycast), + KX_PYMETHODTABLE(KX_NavMeshObject, draw), + KX_PYMETHODTABLE(KX_NavMeshObject, rebuild), + {NULL,NULL} //Sentinel +}; + +KX_PYMETHODDEF_DOC(KX_NavMeshObject, findPath, + "findPath(start, goal): find path from start to goal points\n" + "Returns a path as list of points)\n") +{ + PyObject *ob_from, *ob_to; + if (!PyArg_ParseTuple(args,"OO:getPath",&ob_from,&ob_to)) + return NULL; + MT_Point3 from, to; + if (!PyVecTo(ob_from, from) || !PyVecTo(ob_to, to)) + return NULL; + + float path[MAX_PATH_LEN*3]; + int pathLen = FindPath(from, to, path, MAX_PATH_LEN); + PyObject *pathList = PyList_New( pathLen ); + for (int i=0; i<pathLen; i++) + { + MT_Point3 point(&path[3*i]); + PyList_SET_ITEM(pathList, i, PyObjectFrom(point)); + } + + return pathList; +} + +KX_PYMETHODDEF_DOC(KX_NavMeshObject, raycast, + "raycast(start, goal): raycast from start to goal points\n" + "Returns hit factor)\n") +{ + PyObject *ob_from, *ob_to; + if (!PyArg_ParseTuple(args,"OO:getPath",&ob_from,&ob_to)) + return NULL; + MT_Point3 from, to; + if (!PyVecTo(ob_from, from) || !PyVecTo(ob_to, to)) + return NULL; + float hit = Raycast(from, to); + return PyFloat_FromDouble(hit); +} + +KX_PYMETHODDEF_DOC(KX_NavMeshObject, draw, + "draw(mode): navigation mesh debug drawing\n" + "mode: WALLS, POLYS, TRIS\n") +{ + int arg; + NavMeshRenderMode renderMode = RM_TRIS; + if (PyArg_ParseTuple(args,"i:rebuild",&arg) && arg>=0 && arg<RM_MAX) + renderMode = (NavMeshRenderMode)arg; + DrawNavMesh(renderMode); + Py_RETURN_NONE; +} + +KX_PYMETHODDEF_DOC_NOARGS(KX_NavMeshObject, rebuild, + "rebuild(): rebuild navigation mesh\n") +{ + BuildNavMesh(); + Py_RETURN_NONE; +} + +#endif // DISABLE_PYTHON diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.h b/source/gameengine/Ketsji/KX_NavMeshObject.h new file mode 100644 index 00000000000..78e9488ad1c --- /dev/null +++ b/source/gameengine/Ketsji/KX_NavMeshObject.h @@ -0,0 +1,83 @@ +/** +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ +#ifndef __KX_NAVMESHOBJECT +#define __KX_NAVMESHOBJECT +#include "DetourStatNavMesh.h" +#include "KX_GameObject.h" +#include "PyObjectPlus.h" +#include <vector> + +class RAS_MeshObject; +class MT_Transform; + +class KX_NavMeshObject: public KX_GameObject +{ + Py_Header; + +protected: + dtStatNavMesh* m_navMesh; + + bool BuildVertIndArrays(float *&vertices, int& nverts, + unsigned short* &polys, int& npolys, unsigned short *&dmeshes, + float *&dvertices, int &ndvertsuniq, unsigned short* &dtris, + int& ndtris, int &vertsPerPoly); + +public: + KX_NavMeshObject(void* sgReplicationInfo, SG_Callbacks callbacks); + ~KX_NavMeshObject(); + + virtual CValue* GetReplica(); + virtual void ProcessReplica(); + + + bool BuildNavMesh(); + dtStatNavMesh* GetNavMesh(); + int FindPath(const MT_Point3& from, const MT_Point3& to, float* path, int maxPathLen); + float Raycast(const MT_Point3& from, const MT_Point3& to); + + enum NavMeshRenderMode {RM_WALLS, RM_POLYS, RM_TRIS, RM_MAX}; + void DrawNavMesh(NavMeshRenderMode mode); + void DrawPath(const float *path, int pathLen, const MT_Vector3& color); + + MT_Point3 TransformToLocalCoords(const MT_Point3& wpos); + MT_Point3 TransformToWorldCoords(const MT_Point3& lpos); +#ifndef DISABLE_PYTHON + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + KX_PYMETHOD_DOC(KX_NavMeshObject, findPath); + KX_PYMETHOD_DOC(KX_NavMeshObject, raycast); + KX_PYMETHOD_DOC(KX_NavMeshObject, draw); + KX_PYMETHOD_DOC_NOARGS(KX_NavMeshObject, rebuild); +#endif +}; + +#endif //__KX_NAVMESHOBJECT + diff --git a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp new file mode 100644 index 00000000000..5f78d9a3722 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp @@ -0,0 +1,869 @@ +/** +* Simulation for obstacle avoidance behavior +* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#include "KX_ObstacleSimulation.h" +#include "KX_NavMeshObject.h" +#include "KX_PythonInit.h" +#include "DNA_object_types.h" +#include "BLI_math.h" + +namespace +{ + inline float perp(const MT_Vector2& a, const MT_Vector2& b) { return a.x()*b.y() - a.y()*b.x(); } + + inline float sqr(float x) { return x*x; } + inline float lerp(float a, float b, float t) { return a + (b-a)*t; } + inline float clamp(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } + + inline float vdistsqr(const float* a, const float* b) { return sqr(b[0]-a[0]) + sqr(b[1]-a[1]); } + inline float vdist(const float* a, const float* b) { return sqrtf(vdistsqr(a,b)); } + inline void vcpy(float* a, const float* b) { a[0]=b[0]; a[1]=b[1]; } + inline float vdot(const float* a, const float* b) { return a[0]*b[0] + a[1]*b[1]; } + inline float vperp(const float* a, const float* b) { return a[0]*b[1] - a[1]*b[0]; } + inline void vsub(float* v, const float* a, const float* b) { v[0] = a[0]-b[0]; v[1] = a[1]-b[1]; } + inline void vadd(float* v, const float* a, const float* b) { v[0] = a[0]+b[0]; v[1] = a[1]+b[1]; } + inline void vscale(float* v, const float* a, const float s) { v[0] = a[0]*s; v[1] = a[1]*s; } + inline void vset(float* v, float x, float y) { v[0]=x; v[1]=y; } + inline float vlensqr(const float* v) { return vdot(v,v); } + inline float vlen(const float* v) { return sqrtf(vlensqr(v)); } + inline void vlerp(float* v, const float* a, const float* b, float t) { v[0] = lerp(a[0], b[0], t); v[1] = lerp(a[1], b[1], t); } + inline void vmad(float* v, const float* a, const float* b, float s) { v[0] = a[0] + b[0]*s; v[1] = a[1] + b[1]*s; } + inline void vnorm(float* v) + { + float d = vlen(v); + if (d > 0.0001f) + { + d = 1.0f/d; + v[0] *= d; + v[1] *= d; + } + } +} +inline float triarea(const float* a, const float* b, const float* c) +{ + return (b[0]*a[1] - a[0]*b[1]) + (c[0]*b[1] - b[0]*c[1]) + (a[0]*c[1] - c[0]*a[1]); +} + +static void closestPtPtSeg(const float* pt, + const float* sp, const float* sq, + float& t) +{ + float dir[2],diff[3]; + vsub(dir,sq,sp); + vsub(diff,pt,sp); + t = vdot(diff,dir); + if (t <= 0.0f) { t = 0; return; } + float d = vdot(dir,dir); + if (t >= d) { t = 1; return; } + t /= d; +} + +static float distPtSegSqr(const float* pt, const float* sp, const float* sq) +{ + float t; + closestPtPtSeg(pt, sp,sq, t); + float np[2]; + vlerp(np, sp,sq, t); + return vdistsqr(pt,np); +} + +static int sweepCircleCircle(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v, + const MT_Vector3& pos1, const MT_Scalar r1, + float& tmin, float& tmax) +{ + static const float EPS = 0.0001f; + MT_Vector2 c0(pos0.x(), pos0.y()); + MT_Vector2 c1(pos1.x(), pos1.y()); + MT_Vector2 s = c1 - c0; + MT_Scalar r = r0+r1; + float c = s.length2() - r*r; + float a = v.length2(); + if (a < EPS) return 0; // not moving + + // Overlap, calc time to exit. + float b = MT_dot(v,s); + float d = b*b - a*c; + if (d < 0.0f) return 0; // no intersection. + tmin = (b - sqrtf(d)) / a; + tmax = (b + sqrtf(d)) / a; + return 1; +} + +static int sweepCircleSegment(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v, + const MT_Vector3& pa, const MT_Vector3& pb, const MT_Scalar sr, + float& tmin, float &tmax) +{ + // equation parameters + MT_Vector2 c0(pos0.x(), pos0.y()); + MT_Vector2 sa(pa.x(), pa.y()); + MT_Vector2 sb(pb.x(), pb.y()); + MT_Vector2 L = sb-sa; + MT_Vector2 H = c0-sa; + MT_Scalar radius = r0+sr; + float l2 = L.length2(); + float r2 = radius * radius; + float dl = perp(v, L); + float hl = perp(H, L); + float a = dl * dl; + float b = 2.0f * hl * dl; + float c = hl * hl - (r2 * l2); + float d = (b*b) - (4.0f * a * c); + + // infinite line missed by infinite ray. + if (d < 0.0f) + return 0; + + d = sqrtf(d); + tmin = (-b - d) / (2.0f * a); + tmax = (-b + d) / (2.0f * a); + + // line missed by ray range. + /* if (tmax < 0.0f || tmin > 1.0f) + return 0;*/ + + // find what part of the ray was collided. + MT_Vector2 Pedge; + Pedge = c0+v*tmin; + H = Pedge - sa; + float e0 = MT_dot(H, L) / l2; + Pedge = c0 + v*tmax; + H = Pedge - sa; + float e1 = MT_dot(H, L) / l2; + + if (e0 < 0.0f || e1 < 0.0f) + { + float ctmin, ctmax; + if (sweepCircleCircle(pos0, r0, v, pa, sr, ctmin, ctmax)) + { + if (e0 < 0.0f && ctmin > tmin) + tmin = ctmin; + if (e1 < 0.0f && ctmax < tmax) + tmax = ctmax; + } + else + { + return 0; + } + } + + if (e0 > 1.0f || e1 > 1.0f) + { + float ctmin, ctmax; + if (sweepCircleCircle(pos0, r0, v, pb, sr, ctmin, ctmax)) + { + if (e0 > 1.0f && ctmin > tmin) + tmin = ctmin; + if (e1 > 1.0f && ctmax < tmax) + tmax = ctmax; + } + else + { + return 0; + } + } + + return 1; +} + +static bool inBetweenAngle(float a, float amin, float amax, float& t) +{ + if (amax < amin) amax += (float)M_PI*2; + if (a < amin-(float)M_PI) a += (float)M_PI*2; + if (a > amin+(float)M_PI) a -= (float)M_PI*2; + if (a >= amin && a < amax) + { + t = (a-amin) / (amax-amin); + return true; + } + return false; +} + +static float interpolateToi(float a, const float* dir, const float* toi, const int ntoi) +{ + for (int i = 0; i < ntoi; ++i) + { + int next = (i+1) % ntoi; + float t; + if (inBetweenAngle(a, dir[i], dir[next], t)) + { + return lerp(toi[i], toi[next], t); + } + } + return 0; +} + +KX_ObstacleSimulation::KX_ObstacleSimulation(MT_Scalar levelHeight, bool enableVisualization) +: m_levelHeight(levelHeight) +, m_enableVisualization(enableVisualization) +{ + +} + +KX_ObstacleSimulation::~KX_ObstacleSimulation() +{ + for (size_t i=0; i<m_obstacles.size(); i++) + { + KX_Obstacle* obs = m_obstacles[i]; + delete obs; + } + m_obstacles.clear(); +} +KX_Obstacle* KX_ObstacleSimulation::CreateObstacle(KX_GameObject* gameobj) +{ + KX_Obstacle* obstacle = new KX_Obstacle(); + obstacle->m_gameObj = gameobj; + + vset(obstacle->vel, 0,0); + vset(obstacle->pvel, 0,0); + vset(obstacle->dvel, 0,0); + vset(obstacle->nvel, 0,0); + for (int i = 0; i < VEL_HIST_SIZE; ++i) + vset(&obstacle->hvel[i*2], 0,0); + obstacle->hhead = 0; + + gameobj->RegisterObstacle(this); + m_obstacles.push_back(obstacle); + return obstacle; +} + +void KX_ObstacleSimulation::AddObstacleForObj(KX_GameObject* gameobj) +{ + KX_Obstacle* obstacle = CreateObstacle(gameobj); + struct Object* blenderobject = gameobj->GetBlenderObject(); + obstacle->m_type = KX_OBSTACLE_OBJ; + obstacle->m_shape = KX_OBSTACLE_CIRCLE; + obstacle->m_rad = blenderobject->obstacleRad; +} + +void KX_ObstacleSimulation::AddObstaclesForNavMesh(KX_NavMeshObject* navmeshobj) +{ + dtStatNavMesh* navmesh = navmeshobj->GetNavMesh(); + if (navmesh) + { + int npoly = navmesh->getPolyCount(); + for (int pi=0; pi<npoly; pi++) + { + const dtStatPoly* poly = navmesh->getPoly(pi); + + for (int i = 0, j = (int)poly->nv-1; i < (int)poly->nv; j = i++) + { + if (poly->n[j]) continue; + const float* vj = navmesh->getVertex(poly->v[j]); + const float* vi = navmesh->getVertex(poly->v[i]); + + KX_Obstacle* obstacle = CreateObstacle(navmeshobj); + obstacle->m_type = KX_OBSTACLE_NAV_MESH; + obstacle->m_shape = KX_OBSTACLE_SEGMENT; + obstacle->m_pos = MT_Point3(vj[0], vj[2], vj[1]); + obstacle->m_pos2 = MT_Point3(vi[0], vi[2], vi[1]); + obstacle->m_rad = 0; + } + } + } +} + +void KX_ObstacleSimulation::DestroyObstacleForObj(KX_GameObject* gameobj) +{ + for (size_t i=0; i<m_obstacles.size(); ) + { + if (m_obstacles[i]->m_gameObj == gameobj) + { + KX_Obstacle* obstacle = m_obstacles[i]; + obstacle->m_gameObj->UnregisterObstacle(); + m_obstacles[i] = m_obstacles.back(); + m_obstacles.pop_back(); + delete obstacle; + } + else + i++; + } +} + +void KX_ObstacleSimulation::UpdateObstacles() +{ + for (size_t i=0; i<m_obstacles.size(); i++) + { + if (m_obstacles[i]->m_type==KX_OBSTACLE_NAV_MESH || m_obstacles[i]->m_shape==KX_OBSTACLE_SEGMENT) + continue; + + KX_Obstacle* obs = m_obstacles[i]; + obs->m_pos = obs->m_gameObj->NodeGetWorldPosition(); + obs->vel[0] = obs->m_gameObj->GetLinearVelocity().x(); + obs->vel[1] = obs->m_gameObj->GetLinearVelocity().y(); + + // Update velocity history and calculate perceived (average) velocity. + vcpy(&obs->hvel[obs->hhead*2], obs->vel); + obs->hhead = (obs->hhead+1) % VEL_HIST_SIZE; + vset(obs->pvel,0,0); + for (int j = 0; j < VEL_HIST_SIZE; ++j) + vadd(obs->pvel, obs->pvel, &obs->hvel[j*2]); + vscale(obs->pvel, obs->pvel, 1.0f/VEL_HIST_SIZE); + } +} + +KX_Obstacle* KX_ObstacleSimulation::GetObstacle(KX_GameObject* gameobj) +{ + for (size_t i=0; i<m_obstacles.size(); i++) + { + if (m_obstacles[i]->m_gameObj == gameobj) + return m_obstacles[i]; + } + + return NULL; +} + +void KX_ObstacleSimulation::AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + MT_Vector3& velocity, MT_Scalar maxDeltaSpeed,MT_Scalar maxDeltaAngle) +{ +} + +void KX_ObstacleSimulation::DrawObstacles() +{ + if (!m_enableVisualization) + return; + static const MT_Vector3 bluecolor(0,0,1); + static const MT_Vector3 normal(0.,0.,1.); + static const int SECTORS_NUM = 32; + for (size_t i=0; i<m_obstacles.size(); i++) + { + if (m_obstacles[i]->m_shape==KX_OBSTACLE_SEGMENT) + { + MT_Point3 p1 = m_obstacles[i]->m_pos; + MT_Point3 p2 = m_obstacles[i]->m_pos2; + //apply world transform + if (m_obstacles[i]->m_type == KX_OBSTACLE_NAV_MESH) + { + KX_NavMeshObject* navmeshobj = static_cast<KX_NavMeshObject*>(m_obstacles[i]->m_gameObj); + p1 = navmeshobj->TransformToWorldCoords(p1); + p2 = navmeshobj->TransformToWorldCoords(p2); + } + + KX_RasterizerDrawDebugLine(p1, p2, bluecolor); + } + else if (m_obstacles[i]->m_shape==KX_OBSTACLE_CIRCLE) + { + KX_RasterizerDrawDebugCircle(m_obstacles[i]->m_pos, m_obstacles[i]->m_rad, bluecolor, + normal, SECTORS_NUM); + } + } +} + +static MT_Point3 nearestPointToObstacle(MT_Point3& pos ,KX_Obstacle* obstacle) +{ + switch (obstacle->m_shape) + { + case KX_OBSTACLE_SEGMENT : + { + MT_Vector3 ab = obstacle->m_pos2 - obstacle->m_pos; + if (!ab.fuzzyZero()) + { + MT_Vector3 abdir = ab.normalized(); + MT_Vector3 v = pos - obstacle->m_pos; + MT_Scalar proj = abdir.dot(v); + CLAMP(proj, 0, ab.length()); + MT_Point3 res = obstacle->m_pos + abdir*proj; + return res; + } + } + case KX_OBSTACLE_CIRCLE : + default: + return obstacle->m_pos; + } +} + +static bool filterObstacle(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, KX_Obstacle* otherObst, + float levelHeight) +{ + //filter obstacles by type + if ( (otherObst == activeObst) || + (otherObst->m_type==KX_OBSTACLE_NAV_MESH && otherObst->m_gameObj!=activeNavMeshObj) ) + return false; + + //filter obstacles by position + MT_Point3 p = nearestPointToObstacle(activeObst->m_pos, otherObst); + if ( fabs(activeObst->m_pos.z() - p.z()) > levelHeight) + return false; + + return true; +} + +///////////*********TOI_rays**********///////////////// +KX_ObstacleSimulationTOI::KX_ObstacleSimulationTOI(MT_Scalar levelHeight, bool enableVisualization) +: KX_ObstacleSimulation(levelHeight, enableVisualization), + m_maxSamples(32), + m_minToi(0.0f), + m_maxToi(0.0f), + m_velWeight(1.0f), + m_curVelWeight(1.0f), + m_toiWeight(1.0f), + m_collisionWeight(1.0f) +{ +} + + +void KX_ObstacleSimulationTOI::AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + MT_Vector3& velocity, MT_Scalar maxDeltaSpeed, MT_Scalar maxDeltaAngle) +{ + int nobs = m_obstacles.size(); + int obstidx = std::find(m_obstacles.begin(), m_obstacles.end(), activeObst) - m_obstacles.begin(); + if (obstidx == nobs) + return; + + vset(activeObst->dvel, velocity.x(), velocity.y()); + + //apply RVO + sampleRVO(activeObst, activeNavMeshObj, maxDeltaAngle); + + // Fake dynamic constraint. + float dv[2]; + float vel[2]; + vsub(dv, activeObst->nvel, activeObst->vel); + float ds = vlen(dv); + if (ds > maxDeltaSpeed || ds<-maxDeltaSpeed) + vscale(dv, dv, fabs(maxDeltaSpeed/ds)); + vadd(vel, activeObst->vel, dv); + + velocity.x() = vel[0]; + velocity.y() = vel[1]; +} + +///////////*********TOI_rays**********///////////////// +static const int AVOID_MAX_STEPS = 128; +struct TOICircle +{ + TOICircle() : n(0), minToi(0), maxToi(1) {} + float toi[AVOID_MAX_STEPS]; // Time of impact (seconds) + float toie[AVOID_MAX_STEPS]; // Time of exit (seconds) + float dir[AVOID_MAX_STEPS]; // Direction (radians) + int n; // Number of samples + float minToi, maxToi; // Min/max TOI (seconds) +}; + +KX_ObstacleSimulationTOI_rays::KX_ObstacleSimulationTOI_rays(MT_Scalar levelHeight, bool enableVisualization): + KX_ObstacleSimulationTOI(levelHeight, enableVisualization) +{ + m_maxSamples = 32; + m_minToi = 0.5f; + m_maxToi = 1.2f; + m_velWeight = 4.0f; + m_toiWeight = 1.0f; + m_collisionWeight = 100.0f; +} + + +void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + const float maxDeltaAngle) +{ + MT_Vector2 vel(activeObst->dvel[0], activeObst->dvel[1]); + float vmax = (float) vel.length(); + float odir = (float) atan2(vel.y(), vel.x()); + + MT_Vector2 ddir = vel; + ddir.normalize(); + + float bestScore = FLT_MAX; + float bestDir = odir; + float bestToi = 0; + + TOICircle tc; + tc.n = m_maxSamples; + tc.minToi = m_minToi; + tc.maxToi = m_maxToi; + + const int iforw = m_maxSamples/2; + const float aoff = (float)iforw / (float)m_maxSamples; + + size_t nobs = m_obstacles.size(); + for (int iter = 0; iter < m_maxSamples; ++iter) + { + // Calculate sample velocity + const float ndir = ((float)iter/(float)m_maxSamples) - aoff; + const float dir = odir+ndir*M_PI*2; + MT_Vector2 svel; + svel.x() = cosf(dir) * vmax; + svel.y() = sinf(dir) * vmax; + + // Find min time of impact and exit amongst all obstacles. + float tmin = m_maxToi; + float tmine = 0; + for (int i = 0; i < nobs; ++i) + { + KX_Obstacle* ob = m_obstacles[i]; + bool res = filterObstacle(activeObst, activeNavMeshObj, ob, m_levelHeight); + if (!res) + continue; + + float htmin,htmax; + + if (ob->m_shape == KX_OBSTACLE_CIRCLE) + { + MT_Vector2 vab; + if (vlen(ob->vel) < 0.01f*0.01f) + { + // Stationary, use VO + vab = svel; + } + else + { + // Moving, use RVO + vab = 2*svel - vel - ob->vel; + } + + if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, + vab, ob->m_pos, ob->m_rad, htmin, htmax)) + continue; + } + else if (ob->m_shape == KX_OBSTACLE_SEGMENT) + { + MT_Point3 p1 = ob->m_pos; + MT_Point3 p2 = ob->m_pos2; + //apply world transform + if (ob->m_type == KX_OBSTACLE_NAV_MESH) + { + KX_NavMeshObject* navmeshobj = static_cast<KX_NavMeshObject*>(ob->m_gameObj); + p1 = navmeshobj->TransformToWorldCoords(p1); + p2 = navmeshobj->TransformToWorldCoords(p2); + } + if (!sweepCircleSegment(activeObst->m_pos, activeObst->m_rad, svel, + p1, p2, ob->m_rad, htmin, htmax)) + continue; + } + + if (htmin > 0.0f) + { + // The closest obstacle is somewhere ahead of us, keep track of nearest obstacle. + if (htmin < tmin) + tmin = htmin; + } + else if (htmax > 0.0f) + { + // The agent overlaps the obstacle, keep track of first safe exit. + if (htmax > tmine) + tmine = htmax; + } + } + + // Calculate sample penalties and final score. + const float apen = m_velWeight * fabsf(ndir); + const float tpen = m_toiWeight * (1.0f/(0.0001f+tmin/m_maxToi)); + const float cpen = m_collisionWeight * (tmine/m_minToi)*(tmine/m_minToi); + const float score = apen + tpen + cpen; + + // Update best score. + if (score < bestScore) + { + bestDir = dir; + bestToi = tmin; + bestScore = score; + } + + tc.dir[iter] = dir; + tc.toi[iter] = tmin; + tc.toie[iter] = tmine; + } + + if (vlen(activeObst->vel) > 0.1) + { + // Constrain max turn rate. + float cura = atan2(activeObst->vel[1],activeObst->vel[0]); + float da = bestDir - cura; + if (da < -M_PI) da += (float)M_PI*2; + if (da > M_PI) da -= (float)M_PI*2; + if (da < -maxDeltaAngle) + { + bestDir = cura - maxDeltaAngle; + bestToi = min(bestToi, interpolateToi(bestDir, tc.dir, tc.toi, tc.n)); + } + else if (da > maxDeltaAngle) + { + bestDir = cura + maxDeltaAngle; + bestToi = min(bestToi, interpolateToi(bestDir, tc.dir, tc.toi, tc.n)); + } + } + + // Adjust speed when time of impact is less than min TOI. + if (bestToi < m_minToi) + vmax *= bestToi/m_minToi; + + // New steering velocity. + activeObst->nvel[0] = cosf(bestDir) * vmax; + activeObst->nvel[1] = sinf(bestDir) * vmax; +} + +///////////********* TOI_cells**********///////////////// + +static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + KX_Obstacles& obstacles, float levelHeight, const float vmax, + const float* spos, const float cs, const int nspos, float* res, + float maxToi, float velWeight, float curVelWeight, float sideWeight, + float toiWeight) +{ + vset(res, 0,0); + + const float ivmax = 1.0f / vmax; + + float adir[2], adist; + vcpy(adir, activeObst->pvel); + if (vlen(adir) > 0.01f) + vnorm(adir); + else + vset(adir,0,0); + float activeObstPos[2]; + vset(activeObstPos, activeObst->m_pos.x(), activeObst->m_pos.y()); + adist = vdot(adir, activeObstPos); + + float minPenalty = FLT_MAX; + + for (int n = 0; n < nspos; ++n) + { + float vcand[2]; + vcpy(vcand, &spos[n*2]); + + // Find min time of impact and exit amongst all obstacles. + float tmin = maxToi; + float side = 0; + int nside = 0; + + for (int i = 0; i < obstacles.size(); ++i) + { + KX_Obstacle* ob = obstacles[i]; + bool res = filterObstacle(activeObst, activeNavMeshObj, ob, levelHeight); + if (!res) + continue; + float htmin, htmax; + + if (ob->m_shape==KX_OBSTACLE_CIRCLE) + { + float vab[2]; + + // Moving, use RVO + vscale(vab, vcand, 2); + vsub(vab, vab, activeObst->vel); + vsub(vab, vab, ob->vel); + + // Side + // NOTE: dp, and dv are constant over the whole calculation, + // they can be precomputed per object. + const float* pa = activeObstPos; + float pb[2]; + vset(pb, ob->m_pos.x(), ob->m_pos.y()); + + const float orig[2] = {0,0}; + float dp[2],dv[2],np[2]; + vsub(dp,pb,pa); + vnorm(dp); + vsub(dv,ob->dvel, activeObst->dvel); + + const float a = triarea(orig, dp,dv); + if (a < 0.01f) + { + np[0] = -dp[1]; + np[1] = dp[0]; + } + else + { + np[0] = dp[1]; + np[1] = -dp[0]; + } + + side += clamp(min(vdot(dp,vab)*2,vdot(np,vab)*2), 0.0f, 1.0f); + nside++; + + if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, vab, ob->m_pos, ob->m_rad, + htmin, htmax)) + continue; + + // Handle overlapping obstacles. + if (htmin < 0.0f && htmax > 0.0f) + { + // Avoid more when overlapped. + htmin = -htmin * 0.5f; + } + } + else if (ob->m_shape == KX_OBSTACLE_SEGMENT) + { + MT_Point3 p1 = ob->m_pos; + MT_Point3 p2 = ob->m_pos2; + //apply world transform + if (ob->m_type == KX_OBSTACLE_NAV_MESH) + { + KX_NavMeshObject* navmeshobj = static_cast<KX_NavMeshObject*>(ob->m_gameObj); + p1 = navmeshobj->TransformToWorldCoords(p1); + p2 = navmeshobj->TransformToWorldCoords(p2); + } + float p[2], q[2]; + vset(p, p1.x(), p1.y()); + vset(q, p2.x(), p2.y()); + + // NOTE: the segments are assumed to come from a navmesh which is shrunken by + // the agent radius, hence the use of really small radius. + // This can be handle more efficiently by using seg-seg test instead. + // If the whole segment is to be treated as obstacle, use agent->rad instead of 0.01f! + const float r = 0.01f; // agent->rad + if (distPtSegSqr(activeObstPos, p, q) < sqr(r+ob->m_rad)) + { + float sdir[2], snorm[2]; + vsub(sdir, q, p); + snorm[0] = sdir[1]; + snorm[1] = -sdir[0]; + // If the velocity is pointing towards the segment, no collision. + if (vdot(snorm, vcand) < 0.0f) + continue; + // Else immediate collision. + htmin = 0.0f; + htmax = 10.0f; + } + else + { + if (!sweepCircleSegment(activeObstPos, r, vcand, p, q, ob->m_rad, htmin, htmax)) + continue; + } + + // Avoid less when facing walls. + htmin *= 2.0f; + } + + if (htmin >= 0.0f) + { + // The closest obstacle is somewhere ahead of us, keep track of nearest obstacle. + if (htmin < tmin) + tmin = htmin; + } + } + + // Normalize side bias, to prevent it dominating too much. + if (nside) + side /= nside; + + const float vpen = velWeight * (vdist(vcand, activeObst->dvel) * ivmax); + const float vcpen = curVelWeight * (vdist(vcand, activeObst->vel) * ivmax); + const float spen = sideWeight * side; + const float tpen = toiWeight * (1.0f/(0.1f+tmin/maxToi)); + + const float penalty = vpen + vcpen + spen + tpen; + + if (penalty < minPenalty) + { + minPenalty = penalty; + vcpy(res, vcand); + } + } +} + +void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + const float maxDeltaAngle) +{ + vset(activeObst->nvel, 0.f, 0.f); + float vmax = vlen(activeObst->dvel); + + float* spos = new float[2*m_maxSamples]; + int nspos = 0; + + if (!m_adaptive) + { + const float cvx = activeObst->dvel[0]*m_bias; + const float cvy = activeObst->dvel[1]*m_bias; + float vmax = vlen(activeObst->dvel); + const float vrange = vmax*(1-m_bias); + const float cs = 1.0f / (float)m_sampleRadius*vrange; + + for (int y = -m_sampleRadius; y <= m_sampleRadius; ++y) + { + for (int x = -m_sampleRadius; x <= m_sampleRadius; ++x) + { + if (nspos < m_maxSamples) + { + const float vx = cvx + (float)(x+0.5f)*cs; + const float vy = cvy + (float)(y+0.5f)*cs; + if (vx*vx+vy*vy > sqr(vmax+cs/2)) continue; + spos[nspos*2+0] = vx; + spos[nspos*2+1] = vy; + nspos++; + } + } + } + processSamples(activeObst, activeNavMeshObj, m_obstacles, m_levelHeight, vmax, spos, cs/2, + nspos, activeObst->nvel, m_maxToi, m_velWeight, m_curVelWeight, m_collisionWeight, m_toiWeight); + } + else + { + int rad; + float res[2]; + float cs; + // First sample location. + rad = 4; + res[0] = activeObst->dvel[0]*m_bias; + res[1] = activeObst->dvel[1]*m_bias; + cs = vmax*(2-m_bias*2) / (float)(rad-1); + + for (int k = 0; k < 5; ++k) + { + const float half = (rad-1)*cs*0.5f; + + nspos = 0; + for (int y = 0; y < rad; ++y) + { + for (int x = 0; x < rad; ++x) + { + const float vx = res[0] + x*cs - half; + const float vy = res[1] + y*cs - half; + if (vx*vx+vy*vy > sqr(vmax+cs/2)) continue; + spos[nspos*2+0] = vx; + spos[nspos*2+1] = vy; + nspos++; + } + } + + processSamples(activeObst, activeNavMeshObj, m_obstacles, m_levelHeight, vmax, spos, cs/2, + nspos, res, m_maxToi, m_velWeight, m_curVelWeight, m_collisionWeight, m_toiWeight); + + cs *= 0.5f; + } + vcpy(activeObst->nvel, res); + } +} + +KX_ObstacleSimulationTOI_cells::KX_ObstacleSimulationTOI_cells(MT_Scalar levelHeight, bool enableVisualization) +: KX_ObstacleSimulationTOI(levelHeight, enableVisualization) +, m_bias(0.4f) +, m_adaptive(true) +, m_sampleRadius(15) +{ + m_maxSamples = (m_sampleRadius*2+1)*(m_sampleRadius*2+1) + 100; + m_maxToi = 1.5f; + m_velWeight = 2.0f; + m_curVelWeight = 0.75f; + m_toiWeight = 2.5f; + m_collisionWeight = 0.75f; //side_weight +} diff --git a/source/gameengine/Ketsji/KX_ObstacleSimulation.h b/source/gameengine/Ketsji/KX_ObstacleSimulation.h new file mode 100644 index 00000000000..d926e8deb71 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ObstacleSimulation.h @@ -0,0 +1,145 @@ +/** +* Simulation for obstacle avoidance behavior +* (based on Cane Project - http://code.google.com/p/cane by Mikko Mononen (c) 2009) +* +* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#ifndef __KX_OBSTACLESIMULATION +#define __KX_OBSTACLESIMULATION + +#include <vector> +#include "MT_Point2.h" +#include "MT_Point3.h" + +class KX_GameObject; +class KX_NavMeshObject; + +enum KX_OBSTACLE_TYPE +{ + KX_OBSTACLE_OBJ, + KX_OBSTACLE_NAV_MESH, +}; + +enum KX_OBSTACLE_SHAPE +{ + KX_OBSTACLE_CIRCLE, + KX_OBSTACLE_SEGMENT, +}; + +#define VEL_HIST_SIZE 6 +struct KX_Obstacle +{ + KX_OBSTACLE_TYPE m_type; + KX_OBSTACLE_SHAPE m_shape; + MT_Point3 m_pos; + MT_Point3 m_pos2; + MT_Scalar m_rad; + + float vel[2]; + float pvel[2]; + float dvel[2]; + float nvel[2]; + float hvel[VEL_HIST_SIZE*2]; + int hhead; + + + KX_GameObject* m_gameObj; +}; +typedef std::vector<KX_Obstacle*> KX_Obstacles; + +class KX_ObstacleSimulation +{ +protected: + KX_Obstacles m_obstacles; + + MT_Scalar m_levelHeight; + bool m_enableVisualization; + + KX_Obstacle* CreateObstacle(KX_GameObject* gameobj); +public: + KX_ObstacleSimulation(MT_Scalar levelHeight, bool enableVisualization); + virtual ~KX_ObstacleSimulation(); + + void DrawObstacles(); + //void DebugDraw(); + + void AddObstacleForObj(KX_GameObject* gameobj); + void DestroyObstacleForObj(KX_GameObject* gameobj); + void AddObstaclesForNavMesh(KX_NavMeshObject* navmesh); + KX_Obstacle* GetObstacle(KX_GameObject* gameobj); + void UpdateObstacles(); + virtual void AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + MT_Vector3& velocity, MT_Scalar maxDeltaSpeed,MT_Scalar maxDeltaAngle); + +}; +class KX_ObstacleSimulationTOI: public KX_ObstacleSimulation +{ +protected: + int m_maxSamples; // Number of sample steps + float m_minToi; // Min TOI + float m_maxToi; // Max TOI + float m_velWeight; // Sample selection angle weight + float m_curVelWeight; // Sample selection current velocity weight + float m_toiWeight; // Sample selection TOI weight + float m_collisionWeight; // Sample selection collision weight + + virtual void sampleRVO(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + const float maxDeltaAngle) = 0; +public: + KX_ObstacleSimulationTOI(MT_Scalar levelHeight, bool enableVisualization); + virtual void AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + MT_Vector3& velocity, MT_Scalar maxDeltaSpeed,MT_Scalar maxDeltaAngle); +}; + +class KX_ObstacleSimulationTOI_rays: public KX_ObstacleSimulationTOI +{ +protected: + virtual void sampleRVO(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + const float maxDeltaAngle); +public: + KX_ObstacleSimulationTOI_rays(MT_Scalar levelHeight, bool enableVisualization); +}; + +class KX_ObstacleSimulationTOI_cells: public KX_ObstacleSimulationTOI +{ +protected: + float m_bias; + bool m_adaptive; + int m_sampleRadius; + virtual void sampleRVO(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, + const float maxDeltaAngle); +public: + KX_ObstacleSimulationTOI_cells(MT_Scalar levelHeight, bool enableVisualization); +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index f14d73cb990..62ca2910c60 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -87,6 +87,8 @@ extern "C" { #include "KX_GameActuator.h" #include "KX_ParentActuator.h" #include "KX_SCA_DynamicActuator.h" +#include "KX_SteeringActuator.h" +#include "KX_NavMeshObject.h" #include "SCA_IInputDevice.h" #include "SCA_PropertySensor.h" @@ -181,6 +183,13 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons gp_Rasterizer->DrawDebugLine(from,to,color); } +void KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color, + const MT_Vector3& normal, int nsector) +{ + if (gp_Rasterizer) + gp_Rasterizer->DrawDebugCircle(center, radius, color, normal, nsector); +} + #ifdef WITH_PYTHON static PyObject *gp_OrigPythonSysPath= NULL; @@ -1104,7 +1113,7 @@ static PyObject* gPySetGLSLMaterialSetting(PyObject*, PyObject* args, PyObject*) { - GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm); + GlobalSettings *gs= gp_KetsjiEngine->GetGlobalSettings(); char *setting; int enable, flag, sceneflag; @@ -1118,15 +1127,15 @@ static PyObject* gPySetGLSLMaterialSetting(PyObject*, return NULL; } - sceneflag= gm->flag; + sceneflag= gs->glslflag; if (enable) - gm->flag &= ~flag; + gs->glslflag &= ~flag; else - gm->flag |= flag; + gs->glslflag |= flag; /* display lists and GLSL materials need to be remade */ - if(sceneflag != gm->flag) { + if(sceneflag != gs->glslflag) { GPU_materials_free(); if(gp_KetsjiEngine) { KX_SceneList *scenes = gp_KetsjiEngine->CurrentScenes(); @@ -1147,7 +1156,7 @@ static PyObject* gPyGetGLSLMaterialSetting(PyObject*, PyObject* args, PyObject*) { - GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm); + GlobalSettings *gs= gp_KetsjiEngine->GetGlobalSettings(); char *setting; int enabled = 0, flag; @@ -1161,7 +1170,7 @@ static PyObject* gPyGetGLSLMaterialSetting(PyObject*, return NULL; } - enabled = ((gm->flag & flag) != 0); + enabled = ((gs->glslflag & flag) != 0); return PyLong_FromSsize_t(enabled); } @@ -1173,18 +1182,18 @@ static PyObject* gPySetMaterialType(PyObject*, PyObject* args, PyObject*) { - GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm); + GlobalSettings *gs= gp_KetsjiEngine->GetGlobalSettings(); int type; if (!PyArg_ParseTuple(args,"i:setMaterialType",&type)) return NULL; if(type == KX_BLENDER_GLSL_MATERIAL) - gm->matmode= GAME_MAT_GLSL; + gs->matmode= GAME_MAT_GLSL; else if(type == KX_BLENDER_MULTITEX_MATERIAL) - gm->matmode= GAME_MAT_MULTITEX; + gs->matmode= GAME_MAT_MULTITEX; else if(type == KX_TEXFACE_MATERIAL) - gm->matmode= GAME_MAT_TEXFACE; + gs->matmode= GAME_MAT_TEXFACE; else { PyErr_SetString(PyExc_ValueError, "Rasterizer.setMaterialType(int): material type is not known"); return NULL; @@ -1195,12 +1204,12 @@ static PyObject* gPySetMaterialType(PyObject*, static PyObject* gPyGetMaterialType(PyObject*) { - GameData *gm= &(gp_KetsjiScene->GetBlenderScene()->gm); + GlobalSettings *gs= gp_KetsjiEngine->GetGlobalSettings(); int flag; - if(gm->matmode == GAME_MAT_GLSL) + if(gs->matmode == GAME_MAT_GLSL) flag = KX_BLENDER_GLSL_MATERIAL; - else if(gm->matmode == GAME_MAT_MULTITEX) + else if(gs->matmode == GAME_MAT_MULTITEX) flag = KX_BLENDER_MULTITEX_MATERIAL; else flag = KX_TEXFACE_MATERIAL; @@ -1655,6 +1664,16 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack KX_MACRO_addTypesToDict(d, ROT_MODE_ZXY, ROT_MODE_ZXY); KX_MACRO_addTypesToDict(d, ROT_MODE_ZYX, ROT_MODE_ZYX); + /* Steering actuator */ + KX_MACRO_addTypesToDict(d, KX_STEERING_SEEK, KX_SteeringActuator::KX_STEERING_SEEK); + KX_MACRO_addTypesToDict(d, KX_STEERING_FLEE, KX_SteeringActuator::KX_STEERING_FLEE); + KX_MACRO_addTypesToDict(d, KX_STEERING_PATHFOLLOWING, KX_SteeringActuator::KX_STEERING_PATHFOLLOWING); + + /* KX_NavMeshObject render mode */ + KX_MACRO_addTypesToDict(d, RM_WALLS, KX_NavMeshObject::RM_WALLS); + KX_MACRO_addTypesToDict(d, RM_POLYS, KX_NavMeshObject::RM_POLYS); + KX_MACRO_addTypesToDict(d, RM_TRIS, KX_NavMeshObject::RM_TRIS); + /* BL_Action play modes */ KX_MACRO_addTypesToDict(d, KX_ACTION_MODE_PLAY, BL_Action::ACT_MODE_PLAY); KX_MACRO_addTypesToDict(d, KX_ACTION_MODE_LOOP, BL_Action::ACT_MODE_LOOP); diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 1b172c35eff..d76e8f913df 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -72,6 +72,9 @@ class KX_KetsjiEngine* KX_GetActiveEngine(); #include "MT_Vector3.h" void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color); +void KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color, + const MT_Vector3& normal, int nsector); + #endif //__KX_PYTHON_INIT diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 1c4a17e31fc..49a08135c38 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -68,6 +68,7 @@ #include "KX_SCA_ReplaceMeshActuator.h" #include "KX_SceneActuator.h" #include "KX_StateActuator.h" +#include "KX_SteeringActuator.h" #include "KX_TrackToActuator.h" #include "KX_VehicleWrapper.h" #include "KX_VertexProxy.h" @@ -99,6 +100,7 @@ #include "SCA_PythonController.h" #include "SCA_RandomActuator.h" #include "SCA_IController.h" +#include "KX_NavMeshObject.h" static void PyType_Attr_Set(PyGetSetDef *attr_getset, PyAttributeDef *attr) { @@ -217,9 +219,11 @@ void initPyTypes(void) PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator, init_getset); PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator, init_getset); PyType_Ready_Attr(dict, KX_Scene, init_getset); + PyType_Ready_Attr(dict, KX_NavMeshObject, init_getset); PyType_Ready_Attr(dict, KX_SceneActuator, init_getset); PyType_Ready_Attr(dict, KX_SoundActuator, init_getset); PyType_Ready_Attr(dict, KX_StateActuator, init_getset); + PyType_Ready_Attr(dict, KX_SteeringActuator, init_getset); PyType_Ready_Attr(dict, KX_TouchSensor, init_getset); PyType_Ready_Attr(dict, KX_TrackToActuator, init_getset); PyType_Ready_Attr(dict, KX_VehicleWrapper, init_getset); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 7c76ab01e93..bdc30810b9e 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -87,6 +87,7 @@ #include "BL_ModifierDeformer.h" #include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" +#include "KX_ObstacleSimulation.h" #ifdef USE_BULLET #include "KX_SoftBodyDeformer.h" @@ -214,6 +215,19 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, m_bucketmanager=new RAS_BucketManager(); + bool showObstacleSimulation = scene->gm.flag & GAME_SHOW_OBSTACLE_SIMULATION; + switch (scene->gm.obstacleSimulation) + { + case OBSTSIMULATION_TOI_rays: + m_obstacleSimulation = new KX_ObstacleSimulationTOI_rays((MT_Scalar)scene->gm.levelHeight, showObstacleSimulation); + break; + case OBSTSIMULATION_TOI_cells: + m_obstacleSimulation = new KX_ObstacleSimulationTOI_cells((MT_Scalar)scene->gm.levelHeight, showObstacleSimulation); + break; + default: + m_obstacleSimulation = NULL; + } + #ifdef WITH_PYTHON m_attr_dict = PyDict_New(); /* new ref */ m_draw_call_pre = NULL; @@ -236,6 +250,9 @@ KX_Scene::~KX_Scene() this->RemoveObject(parentobj); } + if (m_obstacleSimulation) + delete m_obstacleSimulation; + if(m_objectlist) m_objectlist->Release(); @@ -1545,6 +1562,10 @@ void KX_Scene::LogicEndFrame() obj->Release(); RemoveObject(obj); } + + //prepare obstacle simulation for new frame + if (m_obstacleSimulation) + m_obstacleSimulation->UpdateObstacles(); } @@ -1977,6 +1998,8 @@ PyMethodDef KX_Scene::Methods[] = { KX_PYMETHODTABLE(KX_Scene, replace), KX_PYMETHODTABLE(KX_Scene, suspend), KX_PYMETHODTABLE(KX_Scene, resume), + KX_PYMETHODTABLE(KX_Scene, drawObstacleSimulation), + /* dict style access */ KX_PYMETHODTABLE(KX_Scene, get), @@ -2301,6 +2324,16 @@ KX_PYMETHODDEF_DOC(KX_Scene, resume, Py_RETURN_NONE; } +KX_PYMETHODDEF_DOC(KX_Scene, drawObstacleSimulation, + "drawObstacleSimulation()\n" + "Draw debug visualization of obstacle simulation.\n") +{ + if (GetObstacleSimulation()) + GetObstacleSimulation()->DrawObstacles(); + + Py_RETURN_NONE; +} + /* Matches python dict.get(key, [default]) */ KX_PYMETHODDEF_DOC(KX_Scene, get, "") { diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 499861bce50..5954d5465ba 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -88,6 +88,7 @@ class SCA_JoystickManager; class btCollisionShape; class KX_BlenderSceneConverter; struct KX_ClientObjectInfo; +class KX_ObstacleSimulation; #ifdef WITH_CXX_GUARDEDALLOC #include "MEM_guardedalloc.h" @@ -293,6 +294,9 @@ protected: struct Scene* m_blenderScene; RAS_2DFilterManager m_filtermanager; + + KX_ObstacleSimulation* m_obstacleSimulation; + public: KX_Scene(class SCA_IInputDevice* keyboarddevice, class SCA_IInputDevice* mousedevice, @@ -585,6 +589,8 @@ public: void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text); void Render2DFilters(RAS_ICanvas* canvas); + KX_ObstacleSimulation* GetObstacleSimulation() {return m_obstacleSimulation;}; + #ifdef WITH_PYTHON /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ @@ -597,6 +603,8 @@ public: KX_PYMETHOD_DOC(KX_Scene, suspend); KX_PYMETHOD_DOC(KX_Scene, resume); KX_PYMETHOD_DOC(KX_Scene, get); + KX_PYMETHOD_DOC(KX_Scene, drawObstacleSimulation); + /* attributes */ static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp new file mode 100644 index 00000000000..a0a2e148c1e --- /dev/null +++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp @@ -0,0 +1,630 @@ +/** +* Add steering behaviors +* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#include "BLI_math.h" +#include "KX_SteeringActuator.h" +#include "KX_GameObject.h" +#include "KX_NavMeshObject.h" +#include "KX_ObstacleSimulation.h" +#include "KX_PythonInit.h" +#include "KX_PyMath.h" +#include "Recast.h" + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, + int mode, + KX_GameObject *target, + KX_GameObject *navmesh, + float distance, + float velocity, + float acceleration, + float turnspeed, + bool isSelfTerminated, + int pathUpdatePeriod, + KX_ObstacleSimulation* simulation, + short facingmode, + bool normalup, + bool enableVisualization) : + SCA_IActuator(gameobj, KX_ACT_STEERING), + m_mode(mode), + m_target(target), + m_distance(distance), + m_velocity(velocity), + m_acceleration(acceleration), + m_turnspeed(turnspeed), + m_isSelfTerminated(isSelfTerminated), + m_pathUpdatePeriod(pathUpdatePeriod), + m_updateTime(0), + m_isActive(false), + m_simulation(simulation), + m_enableVisualization(enableVisualization), + m_facingMode(facingmode), + m_normalUp(normalup), + m_obstacle(NULL), + m_pathLen(0), + m_wayPointIdx(-1), + m_steerVec(MT_Vector3(0, 0, 0)) +{ + m_navmesh = static_cast<KX_NavMeshObject*>(navmesh); + if (m_navmesh) + m_navmesh->RegisterActuator(this); + if (m_target) + m_target->RegisterActuator(this); + + if (m_simulation) + m_obstacle = m_simulation->GetObstacle((KX_GameObject*)gameobj); + KX_GameObject* parent = ((KX_GameObject*)gameobj)->GetParent(); + if (m_facingMode>0 && parent) + { + m_parentlocalmat = parent->GetSGNode()->GetLocalOrientation(); + } + else + m_parentlocalmat.setIdentity(); +} + +KX_SteeringActuator::~KX_SteeringActuator() +{ + if (m_navmesh) + m_navmesh->UnregisterActuator(this); + if (m_target) + m_target->UnregisterActuator(this); +} + +CValue* KX_SteeringActuator::GetReplica() +{ + KX_SteeringActuator* replica = new KX_SteeringActuator(*this); + // replication just copy the m_base pointer => common random generator + replica->ProcessReplica(); + return replica; +} + +void KX_SteeringActuator::ProcessReplica() +{ + if (m_target) + m_target->RegisterActuator(this); + if (m_navmesh) + m_navmesh->RegisterActuator(this); + SCA_IActuator::ProcessReplica(); +} + + +bool KX_SteeringActuator::UnlinkObject(SCA_IObject* clientobj) +{ + if (clientobj == m_target) + { + m_target = NULL; + return true; + } + else if (clientobj == m_navmesh) + { + m_navmesh = NULL; + return true; + } + return false; +} + +void KX_SteeringActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map) +{ + void **h_obj = (*obj_map)[m_target]; + if (h_obj) { + if (m_target) + m_target->UnregisterActuator(this); + m_target = (KX_GameObject*)(*h_obj); + m_target->RegisterActuator(this); + } + + h_obj = (*obj_map)[m_navmesh]; + if (h_obj) { + if (m_navmesh) + m_navmesh->UnregisterActuator(this); + m_navmesh = (KX_NavMeshObject*)(*h_obj); + m_navmesh->RegisterActuator(this); + } +} + +bool KX_SteeringActuator::Update(double curtime, bool frame) +{ + if (frame) + { + double delta = curtime - m_updateTime; + m_updateTime = curtime; + + if (m_posevent && !m_isActive) + { + delta = 0; + m_pathUpdateTime = -1; + m_updateTime = curtime; + m_isActive = true; + } + bool bNegativeEvent = IsNegativeEvent(); + if (bNegativeEvent) + m_isActive = false; + + RemoveAllEvents(); + + if (!delta) + return true; + + if (bNegativeEvent || !m_target) + return false; // do nothing on negative events + + KX_GameObject *obj = (KX_GameObject*) GetParent(); + const MT_Point3& mypos = obj->NodeGetWorldPosition(); + const MT_Point3& targpos = m_target->NodeGetWorldPosition(); + MT_Vector3 vectotarg = targpos - mypos; + MT_Vector3 vectotarg2d = vectotarg; + vectotarg2d.z() = 0; + m_steerVec = MT_Vector3(0, 0, 0); + bool apply_steerforce = false; + bool terminate = true; + + switch (m_mode) { + case KX_STEERING_SEEK: + if (vectotarg2d.length2()>m_distance*m_distance) + { + terminate = false; + m_steerVec = vectotarg; + m_steerVec.normalize(); + apply_steerforce = true; + } + break; + case KX_STEERING_FLEE: + if (vectotarg2d.length2()<m_distance*m_distance) + { + terminate = false; + m_steerVec = -vectotarg; + m_steerVec.normalize(); + apply_steerforce = true; + } + break; + case KX_STEERING_PATHFOLLOWING: + if (m_navmesh && vectotarg.length2()>m_distance*m_distance) + { + terminate = false; + + static const MT_Scalar WAYPOINT_RADIUS(0.25); + + if (m_pathUpdateTime<0 || (m_pathUpdatePeriod>=0 && + curtime - m_pathUpdateTime>((double)m_pathUpdatePeriod/1000))) + { + m_pathUpdateTime = curtime; + m_pathLen = m_navmesh->FindPath(mypos, targpos, m_path, MAX_PATH_LENGTH); + m_wayPointIdx = m_pathLen > 1 ? 1 : -1; + } + + if (m_wayPointIdx>0) + { + MT_Vector3 waypoint(&m_path[3*m_wayPointIdx]); + if ((waypoint-mypos).length2()<WAYPOINT_RADIUS*WAYPOINT_RADIUS) + { + m_wayPointIdx++; + if (m_wayPointIdx>=m_pathLen) + { + m_wayPointIdx = -1; + terminate = true; + } + else + waypoint.setValue(&m_path[3*m_wayPointIdx]); + } + + m_steerVec = waypoint - mypos; + apply_steerforce = true; + + + if (m_enableVisualization) + { + //debug draw + static const MT_Vector3 PATH_COLOR(1,0,0); + m_navmesh->DrawPath(m_path, m_pathLen, PATH_COLOR); + } + } + + } + break; + } + + if (apply_steerforce) + { + bool isdyna = obj->IsDynamic(); + if (isdyna) + m_steerVec.z() = 0; + if (!m_steerVec.fuzzyZero()) + m_steerVec.normalize(); + MT_Vector3 newvel = m_velocity*m_steerVec; + + //adjust velocity to avoid obstacles + if (m_simulation && m_obstacle /*&& !newvel.fuzzyZero()*/) + { + if (m_enableVisualization) + KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(1.,0.,0.)); + m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL, + newvel, m_acceleration*delta, m_turnspeed/180.0f*M_PI*delta); + if (m_enableVisualization) + KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.,1.,0.)); + } + + HandleActorFace(newvel); + if (isdyna) + { + //temporary solution: set 2D steering velocity directly to obj + //correct way is to apply physical force + MT_Vector3 curvel = obj->GetLinearVelocity(); + newvel.z() = curvel.z(); + obj->setLinearVelocity(newvel, false); + } + else + { + MT_Vector3 movement = delta*newvel; + obj->ApplyMovement(movement, false); + } + } + else + { + if (m_simulation && m_obstacle) + { + m_obstacle->dvel[0] = 0.f; + m_obstacle->dvel[1] = 0.f; + } + + } + + if (terminate && m_isSelfTerminated) + return false; + } + + return true; +} + +const MT_Vector3& KX_SteeringActuator::GetSteeringVec() +{ + static MT_Vector3 ZERO_VECTOR(0, 0, 0); + if (m_isActive) + return m_steerVec; + else + return ZERO_VECTOR; +} + +inline float vdot2(const float* a, const float* b) +{ + return a[0]*b[0] + a[2]*b[2]; +} +static bool barDistSqPointToTri(const float* p, const float* a, const float* b, const float* c) +{ + float v0[3], v1[3], v2[3]; + vsub(v0, c,a); + vsub(v1, b,a); + vsub(v2, p,a); + + const float dot00 = vdot2(v0, v0); + const float dot01 = vdot2(v0, v1); + const float dot02 = vdot2(v0, v2); + const float dot11 = vdot2(v1, v1); + const float dot12 = vdot2(v1, v2); + + // Compute barycentric coordinates + float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); + float u = (dot11 * dot02 - dot01 * dot12) * invDenom; + float v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + float ud = u<0.f ? -u : (u>1.f ? u-1.f : 0.f); + float vd = v<0.f ? -v : (v>1.f ? v-1.f : 0.f); + return ud*ud+vd*vd ; +} + +inline void flipAxes(float* vec) +{ + std::swap(vec[1],vec[2]); +} + +static bool getNavmeshNormal(dtStatNavMesh* navmesh, const MT_Vector3& pos, MT_Vector3& normal) +{ + static const float polyPickExt[3] = {2, 4, 2}; + float spos[3]; + pos.getValue(spos); + flipAxes(spos); + dtStatPolyRef sPolyRef = navmesh->findNearestPoly(spos, polyPickExt); + if (sPolyRef == 0) + return false; + const dtStatPoly* p = navmesh->getPoly(sPolyRef-1); + const dtStatPolyDetail* pd = navmesh->getPolyDetail(sPolyRef-1); + + float distMin = FLT_MAX; + int idxMin = -1; + for (int i = 0; i < pd->ntris; ++i) + { + const unsigned char* t = navmesh->getDetailTri(pd->tbase+i); + const float* v[3]; + for (int j = 0; j < 3; ++j) + { + if (t[j] < p->nv) + v[j] = navmesh->getVertex(p->v[t[j]]); + else + v[j] = navmesh->getDetailVertex(pd->vbase+(t[j]-p->nv)); + } + float dist = barDistSqPointToTri(spos, v[0], v[1], v[2]); + if (dist<distMin) + { + distMin = dist; + idxMin = i; + } + } + + if (idxMin>=0) + { + const unsigned char* t = navmesh->getDetailTri(pd->tbase+idxMin); + const float* v[3]; + for (int j = 0; j < 3; ++j) + { + if (t[j] < p->nv) + v[j] = navmesh->getVertex(p->v[t[j]]); + else + v[j] = navmesh->getDetailVertex(pd->vbase+(t[j]-p->nv)); + } + MT_Vector3 tri[3]; + for (size_t j=0; j<3; j++) + tri[j].setValue(v[j][0],v[j][2],v[j][1]); + MT_Vector3 a,b; + a = tri[1]-tri[0]; + b = tri[2]-tri[0]; + normal = b.cross(a).safe_normalized(); + return true; + } + + return false; +} + +void KX_SteeringActuator::HandleActorFace(MT_Vector3& velocity) +{ + if (m_facingMode==0 && (!m_navmesh || !m_normalUp)) + return; + KX_GameObject* curobj = (KX_GameObject*) GetParent(); + MT_Vector3 dir = m_facingMode==0 ? curobj->NodeGetLocalOrientation().getColumn(1) : velocity; + if (dir.fuzzyZero()) + return; + dir.normalize(); + MT_Vector3 up(0,0,1); + MT_Vector3 left; + MT_Matrix3x3 mat; + + if (m_navmesh && m_normalUp) + { + dtStatNavMesh* navmesh = m_navmesh->GetNavMesh(); + MT_Vector3 normal; + MT_Vector3 trpos = m_navmesh->TransformToLocalCoords(curobj->NodeGetWorldPosition()); + if (getNavmeshNormal(navmesh, trpos, normal)) + { + + left = (dir.cross(up)).safe_normalized(); + dir = (-left.cross(normal)).safe_normalized(); + up = normal; + } + } + + switch (m_facingMode) + { + case 1: // TRACK X + { + left = dir.safe_normalized(); + dir = -(left.cross(up)).safe_normalized(); + break; + }; + case 2: // TRACK Y + { + left = (dir.cross(up)).safe_normalized(); + break; + } + + case 3: // track Z + { + left = up.safe_normalized(); + up = dir.safe_normalized(); + dir = left; + left = (dir.cross(up)).safe_normalized(); + break; + } + + case 4: // TRACK -X + { + left = -dir.safe_normalized(); + dir = -(left.cross(up)).safe_normalized(); + break; + }; + case 5: // TRACK -Y + { + left = (-dir.cross(up)).safe_normalized(); + dir = -dir; + break; + } + case 6: // track -Z + { + left = up.safe_normalized(); + up = -dir.safe_normalized(); + dir = left; + left = (dir.cross(up)).safe_normalized(); + break; + } + } + + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + + + + KX_GameObject* parentObject = curobj->GetParent(); + if(parentObject) + { + MT_Point3 localpos; + localpos = curobj->GetSGNode()->GetLocalPosition(); + MT_Matrix3x3 parentmatinv; + parentmatinv = parentObject->NodeGetWorldOrientation ().inverse (); + mat = parentmatinv * mat; + mat = m_parentlocalmat * mat; + curobj->NodeSetLocalOrientation(mat); + curobj->NodeSetLocalPosition(localpos); + } + else + { + curobj->NodeSetLocalOrientation(mat); + } + +} + +#ifndef DISABLE_PYTHON + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_SteeringActuator::Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "KX_SteeringActuator", + sizeof(PyObjectPlus_Proxy), + 0, + py_base_dealloc, + 0, + 0, + 0, + 0, + py_base_repr, + 0,0,0,0,0,0,0,0,0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new +}; + +PyMethodDef KX_SteeringActuator::Methods[] = { + {NULL,NULL} //Sentinel +}; + +PyAttributeDef KX_SteeringActuator::Attributes[] = { + KX_PYATTRIBUTE_INT_RW("behaviour", KX_STEERING_NODEF+1, KX_STEERING_MAX-1, true, KX_SteeringActuator, m_mode), + KX_PYATTRIBUTE_RW_FUNCTION("target", KX_SteeringActuator, pyattr_get_target, pyattr_set_target), + KX_PYATTRIBUTE_RW_FUNCTION("navmesh", KX_SteeringActuator, pyattr_get_navmesh, pyattr_set_navmesh), + KX_PYATTRIBUTE_FLOAT_RW("distance", 0.0f, 1000.0f, KX_SteeringActuator, m_distance), + KX_PYATTRIBUTE_FLOAT_RW("velocity", 0.0f, 1000.0f, KX_SteeringActuator, m_velocity), + KX_PYATTRIBUTE_FLOAT_RW("acceleration", 0.0f, 1000.0f, KX_SteeringActuator, m_acceleration), + KX_PYATTRIBUTE_FLOAT_RW("turnspeed", 0.0f, 720.0f, KX_SteeringActuator, m_turnspeed), + KX_PYATTRIBUTE_BOOL_RW("selfterminated", KX_SteeringActuator, m_isSelfTerminated), + KX_PYATTRIBUTE_BOOL_RW("enableVisualization", KX_SteeringActuator, m_enableVisualization), + KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec), + KX_PYATTRIBUTE_SHORT_RW("facingMode", 0, 6, true, KX_SteeringActuator, m_facingMode), + KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod), + { NULL } //Sentinel +}; + +PyObject* KX_SteeringActuator::pyattr_get_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); + if (!actuator->m_target) + Py_RETURN_NONE; + else + return actuator->m_target->GetProxy(); +} + +int KX_SteeringActuator::pyattr_set_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); + KX_GameObject *gameobj; + + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SteeringActuator")) + return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error + + if (actuator->m_target != NULL) + actuator->m_target->UnregisterActuator(actuator); + + actuator->m_target = (KX_GameObject*) gameobj; + + if (actuator->m_target) + actuator->m_target->RegisterActuator(actuator); + + return PY_SET_ATTR_SUCCESS; +} + +PyObject* KX_SteeringActuator::pyattr_get_navmesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); + if (!actuator->m_navmesh) + Py_RETURN_NONE; + else + return actuator->m_navmesh->GetProxy(); +} + +int KX_SteeringActuator::pyattr_set_navmesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); + KX_GameObject *gameobj; + + if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SteeringActuator")) + return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error + + if (!PyObject_TypeCheck(value, &KX_NavMeshObject::Type)) + { + PyErr_Format(PyExc_TypeError, "KX_NavMeshObject is expected"); + return PY_SET_ATTR_FAIL; + } + + if (actuator->m_navmesh != NULL) + actuator->m_navmesh->UnregisterActuator(actuator); + + actuator->m_navmesh = static_cast<KX_NavMeshObject*>(gameobj); + + if (actuator->m_navmesh) + actuator->m_navmesh->RegisterActuator(actuator); + + return PY_SET_ATTR_SUCCESS; +} + +PyObject* KX_SteeringActuator::pyattr_get_steeringVec(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); + const MT_Vector3& steeringVec = actuator->GetSteeringVec(); + return PyObjectFrom(steeringVec); +} + +#endif // DISABLE_PYTHON + +/* eof */ + diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h new file mode 100644 index 00000000000..4f8303107f7 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SteeringActuator.h @@ -0,0 +1,130 @@ +/** +* Add steering behaviors +* +* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#ifndef __KX_STEERINGACTUATOR +#define __KX_STEERINGACTUATOR + +#include "SCA_IActuator.h" +#include "SCA_LogicManager.h" +#include "MT_Matrix3x3.h" + +class KX_GameObject; +class KX_NavMeshObject; +struct KX_Obstacle; +class KX_ObstacleSimulation; +const int MAX_PATH_LENGTH = 128; + +class KX_SteeringActuator : public SCA_IActuator +{ + Py_Header; + + /** Target object */ + KX_GameObject *m_target; + KX_NavMeshObject *m_navmesh; + int m_mode; + float m_distance; + float m_velocity; + float m_acceleration; + float m_turnspeed; + KX_ObstacleSimulation* m_simulation; + + KX_Obstacle* m_obstacle; + double m_updateTime; + bool m_isActive; + bool m_isSelfTerminated; + bool m_enableVisualization; + short m_facingMode; + bool m_normalUp; + float m_path[MAX_PATH_LENGTH*3]; + int m_pathLen; + int m_pathUpdatePeriod; + double m_pathUpdateTime; + int m_wayPointIdx; + MT_Matrix3x3 m_parentlocalmat; + MT_Vector3 m_steerVec; + void HandleActorFace(MT_Vector3& velocity); +public: + enum KX_STEERINGACT_MODE + { + KX_STEERING_NODEF = 0, + KX_STEERING_SEEK, + KX_STEERING_FLEE, + KX_STEERING_PATHFOLLOWING, + KX_STEERING_MAX + }; + + KX_SteeringActuator(class SCA_IObject* gameobj, + int mode, + KX_GameObject *target, + KX_GameObject *navmesh, + float distance, + float velocity, + float acceleration, + float turnspeed, + bool isSelfTerminated, + int pathUpdatePeriod, + KX_ObstacleSimulation* simulation, + short facingmode, + bool normalup, + bool enableVisualization); + virtual ~KX_SteeringActuator(); + virtual bool Update(double curtime, bool frame); + + virtual CValue* GetReplica(); + virtual void ProcessReplica(); + virtual void Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map); + virtual bool UnlinkObject(SCA_IObject* clientobj); + const MT_Vector3& GetSteeringVec(); + +#ifndef DISABLE_PYTHON + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + /* These are used to get and set m_target */ + static PyObject* pyattr_get_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_navmesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_navmesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_steeringVec(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + + +#endif // DISABLE_PYTHON + +}; /* end of class KX_SteeringActuator : public SCA_PropertyActuator */ + +#endif + diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index c5509dd7de8..9b453ed76d5 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -20,6 +20,7 @@ incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/ga incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common' incs += ' #source/gameengine/Physics/Dummy' incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include #source/blender/gpu' +incs += ' #extern/recastnavigation/Recast/Include #extern/recastnavigation/Detour/Include' incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index c46ebf742a0..877a7219a1c 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -393,7 +393,9 @@ public: virtual void SetPolygonOffset(float mult, float add) = 0; virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)=0; - virtual void FlushDebugLines()=0; + virtual void DrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color, + const MT_Vector3& normal, int nsector)=0; + virtual void FlushDebugShapes()=0; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 50d034a5a5a..6ad9e591474 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -55,6 +55,10 @@ #include "BKE_DerivedMesh.h" +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + /** * 32x32 bit masks for vinterlace stereo mode */ @@ -354,9 +358,9 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void) m_materialCachingInfo = 0; } -void RAS_OpenGLRasterizer::FlushDebugLines() +void RAS_OpenGLRasterizer::FlushDebugShapes() { - if(!m_debugLines.size()) + if(!m_debugShapes.size()) return; // DrawDebugLines @@ -368,29 +372,67 @@ void RAS_OpenGLRasterizer::FlushDebugLines() if(light) glDisable(GL_LIGHTING); if(tex) glDisable(GL_TEXTURE_2D); + //draw lines glBegin(GL_LINES); - for (unsigned int i=0;i<m_debugLines.size();i++) + for (unsigned int i=0;i<m_debugShapes.size();i++) { - glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f); - const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x(); - const MT_Scalar* toPtr= &m_debugLines[i].m_to.x(); - + if (m_debugShapes[i].m_type != OglDebugShape::LINE) + continue; + glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); + const MT_Scalar* fromPtr = &m_debugShapes[i].m_pos.x(); + const MT_Scalar* toPtr= &m_debugShapes[i].m_param.x(); glVertex3dv(fromPtr); glVertex3dv(toPtr); } glEnd(); + //draw circles + for (unsigned int i=0;i<m_debugShapes.size();i++) + { + if (m_debugShapes[i].m_type != OglDebugShape::CIRCLE) + continue; + glBegin(GL_LINE_LOOP); + glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); + + static const MT_Vector3 worldUp(0.,0.,1.); + MT_Vector3 norm = m_debugShapes[i].m_param; + MT_Matrix3x3 tr; + if (norm.fuzzyZero() || norm == worldUp) + { + tr.setIdentity(); + } + else + { + MT_Vector3 xaxis, yaxis; + xaxis = MT_cross(norm, worldUp); + yaxis = MT_cross(xaxis, norm); + tr.setValue(xaxis.x(), xaxis.y(), xaxis.z(), + yaxis.x(), yaxis.y(), yaxis.z(), + norm.x(), norm.y(), norm.z()); + } + MT_Scalar rad = m_debugShapes[i].m_param2.x(); + int n = (int) m_debugShapes[i].m_param2.y(); + for (int j = 0; j<n; j++) + { + MT_Scalar theta = j*M_PI*2/n; + MT_Vector3 pos(cos(theta)*rad, sin(theta)*rad, 0.); + pos = pos*tr; + pos += m_debugShapes[i].m_pos; + const MT_Scalar* posPtr = &pos.x(); + glVertex3dv(posPtr); + } + glEnd(); + } + if(light) glEnable(GL_LIGHTING); if(tex) glEnable(GL_TEXTURE_2D); - m_debugLines.clear(); + m_debugShapes.clear(); } void RAS_OpenGLRasterizer::EndFrame() { - - - FlushDebugLines(); + FlushDebugShapes(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 61568df91eb..c0e02f6df77 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -49,10 +49,15 @@ using namespace std; #define RAS_MAX_TEXCO 8 // match in BL_Material #define RAS_MAX_ATTRIB 16 // match in BL_BlenderShader -struct OglDebugLine +struct OglDebugShape { - MT_Vector3 m_from; - MT_Vector3 m_to; + enum SHAPE_TYPE{ + LINE, CIRCLE + }; + SHAPE_TYPE m_type; + MT_Vector3 m_pos; + MT_Vector3 m_param; + MT_Vector3 m_param2; MT_Vector3 m_color; }; @@ -256,18 +261,32 @@ public: virtual void SetPolygonOffset(float mult, float add); - virtual void FlushDebugLines(); + virtual void FlushDebugShapes(); - virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) + virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) { - OglDebugLine line; - line.m_from = from; - line.m_to = to; + OglDebugShape line; + line.m_type = OglDebugShape::LINE; + line.m_pos= from; + line.m_param = to; line.m_color = color; - m_debugLines.push_back(line); + m_debugShapes.push_back(line); + } + + virtual void DrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color, + const MT_Vector3& normal, int nsector) + { + OglDebugShape line; + line.m_type = OglDebugShape::CIRCLE; + line.m_pos= center; + line.m_param = normal; + line.m_color = color; + line.m_param2.x() = radius; + line.m_param2.y() = (float) nsector; + m_debugShapes.push_back(line); } - std::vector <OglDebugLine> m_debugLines; + std::vector <OglDebugShape> m_debugShapes; virtual void SetTexCoordNum(int num); virtual void SetAttribNum(int num); diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 2cb3831de52..e7244265fc4 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -112,7 +112,7 @@ static PyMethodDef moduleMethods[] = {NULL} /* Sentinel */ }; -#if WITH_FFMPEG +#ifdef WITH_FFMPEG extern PyTypeObject VideoFFmpegType; extern PyTypeObject ImageFFmpegType; #endif @@ -134,7 +134,7 @@ extern PyTypeObject ImageViewportType; static void registerAllTypes(void) { -#if WITH_FFMPEG +#ifdef WITH_FFMPEG pyImageTypes.add(&VideoFFmpegType, "VideoFFmpeg"); pyImageTypes.add(&ImageFFmpegType, "ImageFFmpeg"); #endif |