Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • Alexandre.Meyer/m1if37-animation
  • Alexandre.Meyer/m2-apprentissage-profond-image
  • Alexandre.Meyer/m2-animation
  • Alexandre.Meyer/hugo-web-minimal
  • Alexandre.Meyer/lifami
  • Alexandre.Meyer/lifapcd
  • Alexandre.Meyer/www
  • Alexandre.Meyer/lifstage
8 results
Show changes
Showing
with 0 additions and 2840 deletions
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="Modules.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lend"
style="overflow:visible;">
<path
id="path3683"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) rotate(180) translate(1,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2838"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2860"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2888"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2845"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2867"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-21.80283"
inkscape:cy="542.76881"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1138"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#d7e3f4;fill-opacity:1;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2820-7-9-1-7"
width="120"
height="46"
x="183"
y="416.36218"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<rect
style="fill:#d7e3f4;fill-opacity:1;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2820-7-9-1"
width="120"
height="46"
x="279.625"
y="324.36218"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="310.13672"
y="351.92664"
id="text2826"
sodipodi:linespacing="125%"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><tspan
sodipodi:role="line"
id="tspan2828"
x="310.13672"
y="351.92664">Common</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="215.79297"
y="442.92664"
id="text2826-4"
sodipodi:linespacing="125%"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><tspan
sodipodi:role="line"
id="tspan2828-0"
x="215.79297"
y="442.92664">Collision</tspan></text>
<rect
style="fill:#d7e3f4;fill-opacity:1;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2820-7-9"
width="120"
height="46"
x="279.625"
y="507.36218"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="307.94531"
y="535.92664"
id="text2826-4-4"
sodipodi:linespacing="125%"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><tspan
sodipodi:role="line"
id="tspan2828-0-8"
x="307.94531"
y="535.92664">Dynamics</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 315.46875,370.36218 -48.3125,46"
id="path2881"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect2820-7-9-1"
inkscape:connection-end="#rect2820-7-9-1-7"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 267.4217,462.36218 47.7816,45"
id="path2883"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect2820-7-9-1-7"
inkscape:connection-end="#rect2820-7-9"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 339.625,370.36218 0,137"
id="path2885"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect2820-7-9-1"
inkscape:connection-end="#rect2820-7-9"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\modules.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg3598"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="raycast.svg"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\raycast.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs3600">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Mend"
style="overflow:visible;">
<path
id="path4314"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(0.6) rotate(180) translate(0,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3606" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="297"
inkscape:cy="520"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1246"
inkscape:window-height="849"
inkscape:window-x="100"
inkscape:window-y="100"
inkscape:window-maximized="0" />
<metadata
id="metadata3603">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
y="473.70428"
x="232.34212"
height="16.815773"
width="19.815773"
id="rect4120"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="429.19492"
x="378.33273"
height="36.334541"
width="54.334541"
id="rect4122"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="548.88507"
x="222.02287"
height="21.954247"
width="35.454247"
id="rect4124"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="508.34296"
x="408.48077"
height="20.538485"
width="32.038483"
id="rect4126"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="524.32886"
x="306.46667"
height="61.066628"
width="43.566628"
id="rect4128"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="429.74796"
x="292.88577"
height="66.228439"
width="33.728436"
id="rect4130"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect4276"
width="33.790939"
height="30.790941"
x="374.60455"
y="547.46674" />
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect4278"
width="49.259716"
height="43.759716"
x="210.37013"
y="406.7323" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:1,2;marker-end:url(#Arrow2Mend);stroke-dashoffset:0"
d="m 413.96525,367.89693 -219.9305,175.4305"
id="path4282" />
<path
id="path4732"
d="m 414.26779,367.59439 -86.85587,69.28175"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Mend)" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="310.5"
y="614.36218"
id="text4734"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4742"
x="310.5"
y="614.36218">ray cast</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg3598"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="regionquery.svg"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\regionquery.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs3600">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Mend"
style="overflow:visible;">
<path
id="path4314"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(0.6) rotate(180) translate(0,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3606" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="219"
inkscape:cy="520"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1138"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata3603">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
y="473.70428"
x="232.34212"
height="16.815773"
width="19.815773"
id="rect4120"
style="fill:none;stroke:#00d200;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="429.19492"
x="378.33273"
height="36.334541"
width="54.334541"
id="rect4122"
style="fill:none;stroke:#00d200;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="548.88507"
x="222.02287"
height="21.954247"
width="35.454247"
id="rect4124"
style="fill:none;stroke:#00d200;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="508.34296"
x="408.48077"
height="20.538485"
width="32.038483"
id="rect4126"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="524.32886"
x="306.46667"
height="61.066628"
width="43.566628"
id="rect4128"
style="fill:none;stroke:#00d200;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="429.74796"
x="292.88577"
height="66.228439"
width="33.728436"
id="rect4130"
style="fill:none;stroke:#00d200;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
style="fill:none;stroke:#00d200;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect4276"
width="33.790939"
height="30.790941"
x="374.60455"
y="547.46674" />
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect4278"
width="49.259716"
height="43.759716"
x="210.37013"
y="406.7323" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="310.5"
y="614.36218"
id="text4734"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3606">region query</tspan></text>
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2, 4;stroke-dashoffset:0"
id="rect2826"
width="149.5"
height="128"
x="248"
y="462.36218" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="tunneling.svg"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\tunneling.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Mend"
style="overflow:visible;">
<path
id="path3648"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(0.6) rotate(180) translate(0,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective3602"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="292"
inkscape:cy="544"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1390"
inkscape:window-height="1038"
inkscape:window-x="50"
inkscape:window-y="50"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect2816"
width="233"
height="13.5"
x="210.5"
y="541.86218" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3592"
sodipodi:cx="295.25"
sodipodi:cy="494.11218"
sodipodi:rx="6.25"
sodipodi:ry="6.25"
d="m 301.5,494.11218 a 6.25,6.25 0 1 1 -12.5,0 6.25,6.25 0 1 1 12.5,0 z"
transform="translate(7.5,3)" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3592-1"
sodipodi:cx="295.25"
sodipodi:cy="494.11218"
sodipodi:rx="6.25"
sodipodi:ry="6.25"
d="m 301.5,494.11218 a 6.25,6.25 0 1 1 -12.5,0 6.25,6.25 0 1 1 12.5,0 z"
transform="translate(7.5,91.25)" />
<path
style="fill:none;stroke:#000000;stroke-width:0.93691868;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.93691866, 1.87383732;stroke-dashoffset:0;marker-end:url(#Arrow2Mend)"
d="m 302.99984,505.33064 0,71.67556"
id="path3616" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="319"
y="499.86218"
id="text4066"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4068"
x="319"
y="499.86218">t=0</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4070"
y="587.86218"
x="319"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
xml:space="preserve"><tspan
sodipodi:role="line"
id="tspan4074">t=1</tspan></text>
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Calibri;-inkscape-font-specification:Calibri"
x="300"
y="620.86218"
id="text4076"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4078"
x="300"
y="620.86218">tunneling</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="winding.svg"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow2Mstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Mstart"
style="overflow:visible">
<path
id="path3660"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(0.6) translate(0,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Mend"
style="overflow:visible;">
<path
id="path3663"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(0.6) rotate(180) translate(0,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;">
<path
id="path3645"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lend"
style="overflow:visible;">
<path
id="path3657"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) rotate(180) translate(1,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;">
<path
id="path3639"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lstart"
style="overflow:visible">
<path
id="path3654"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) translate(1,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2835"
inkscape:persp3d-origin="292.5 : 75.212601 : 1"
inkscape:vp_z="585 : 112.8189 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 112.8189 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="144.24667"
inkscape:cy="588.82527"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1737"
inkscape:window-height="1054"
inkscape:window-x="25"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
id="2"
xml:space="preserve"
x="592.97321"
y="557.97272"
style="font-size:13.80000019px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Calibri"> </text>
<text
id="6"
xml:space="preserve"
x="476.47318"
y="507.86407"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Calibri;-inkscape-font-specification:Calibri"
sodipodi:linespacing="125%"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">x</text>
<text
id="7"
xml:space="preserve"
x="482.47318"
y="507.86407"
style="font-size:13.80000019px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Calibri"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"> </text>
<text
id="8"
xml:space="preserve"
x="387.67319"
y="387.19345"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Calibri;-inkscape-font-specification:Calibri"
sodipodi:linespacing="125%"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">y</text>
<text
id="9"
xml:space="preserve"
x="396.32318"
y="383.19345"
style="font-size:13.80000019px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Calibri"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"> </text>
<text
id="11"
xml:space="preserve"
x="245.37318"
y="420.09586"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Calibri;-inkscape-font-specification:Calibri"
sodipodi:linespacing="125%"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">CCW winding</text>
<text
id="12"
xml:space="preserve"
x="294.62317"
y="397.59586"
style="font-size:13.80000019px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;font-family:Calibri"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"> </text>
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
d="m 345.5,414.36218 -56.5,34"
id="path4267"
sodipodi:nodetypes="cc"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
style="fill:#d7e3f4;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="m 289.5,466.36218 26,47.5 57.5,43.5 77.5,-70 -17,-61.5 -70.5,-4 -73.5,44.5 z"
id="path5829"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow2Mstart);marker-end:url(#Arrow2Mend)"
d="m 384,392.86218 0,101 95.5,0"
id="path5241"
inkscape:export-filename="D:\Development\Box2D\Box2D\Documentation\images\winding.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</svg>
File deleted
File deleted
/*
* Copyright (c) 2006-2013 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "DebugDraw.h"
#if defined(__APPLE_CC__)
#include <OpenGL/gl3.h>
#else
#include "glew/glew.h"
#endif
#include "glfw/glfw3.h"
#include <stdio.h>
#include <stdarg.h>
#include "imgui/imgui.h"
#define BUFFER_OFFSET(x) ((const void*) (x))
DebugDraw g_debugDraw;
Camera g_camera;
//
b2Vec2 Camera::ConvertScreenToWorld(const b2Vec2& ps)
{
float32 w = float32(m_width);
float32 h = float32(m_height);
float32 u = ps.x / w;
float32 v = (h - ps.y) / h;
float32 ratio = w / h;
b2Vec2 extents(ratio * 25.0f, 25.0f);
extents *= m_zoom;
b2Vec2 lower = m_center - extents;
b2Vec2 upper = m_center + extents;
b2Vec2 pw;
pw.x = (1.0f - u) * lower.x + u * upper.x;
pw.y = (1.0f - v) * lower.y + v * upper.y;
return pw;
}
//
b2Vec2 Camera::ConvertWorldToScreen(const b2Vec2& pw)
{
float32 w = float32(m_width);
float32 h = float32(m_height);
float32 ratio = w / h;
b2Vec2 extents(ratio * 25.0f, 25.0f);
extents *= m_zoom;
b2Vec2 lower = m_center - extents;
b2Vec2 upper = m_center + extents;
float32 u = (pw.x - lower.x) / (upper.x - lower.x);
float32 v = (pw.y - lower.y) / (upper.y - lower.y);
b2Vec2 ps;
ps.x = u * w;
ps.y = (1.0f - v) * h;
return ps;
}
// Convert from world coordinates to normalized device coordinates.
// http://www.songho.ca/opengl/gl_projectionmatrix.html
void Camera::BuildProjectionMatrix(float32* m, float32 zBias)
{
float32 w = float32(m_width);
float32 h = float32(m_height);
float32 ratio = w / h;
b2Vec2 extents(ratio * 25.0f, 25.0f);
extents *= m_zoom;
b2Vec2 lower = m_center - extents;
b2Vec2 upper = m_center + extents;
m[0] = 2.0f / (upper.x - lower.x);
m[1] = 0.0f;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = 0.0f;
m[5] = 2.0f / (upper.y - lower.y);
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m[12] = -(upper.x + lower.x) / (upper.x - lower.x);
m[13] = -(upper.y + lower.y) / (upper.y - lower.y);
m[14] = zBias;
m[15] = 1.0f;
}
//
static void sCheckGLError()
{
GLenum errCode = glGetError();
if (errCode != GL_NO_ERROR)
{
fprintf(stderr, "OpenGL error = %d\n", errCode);
assert(false);
}
}
// Prints shader compilation errors
static void sPrintLog(GLuint object)
{
GLint log_length = 0;
if (glIsShader(object))
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
else if (glIsProgram(object))
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
else
{
fprintf(stderr, "printlog: Not a shader or a program\n");
return;
}
char* log = (char*)malloc(log_length);
if (glIsShader(object))
glGetShaderInfoLog(object, log_length, NULL, log);
else if (glIsProgram(object))
glGetProgramInfoLog(object, log_length, NULL, log);
fprintf(stderr, "%s", log);
free(log);
}
//
static GLuint sCreateShaderFromString(const char* source, GLenum type)
{
GLuint res = glCreateShader(type);
const char* sources[] = { source };
glShaderSource(res, 1, sources, NULL);
glCompileShader(res);
GLint compile_ok = GL_FALSE;
glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
if (compile_ok == GL_FALSE)
{
fprintf(stderr, "Error compiling shader of type %d!\n", type);
sPrintLog(res);
glDeleteShader(res);
return 0;
}
return res;
}
//
static GLuint sCreateShaderProgram(const char* vs, const char* fs)
{
GLuint vsId = sCreateShaderFromString(vs, GL_VERTEX_SHADER);
GLuint fsId = sCreateShaderFromString(fs, GL_FRAGMENT_SHADER);
assert(vsId != 0 && fsId != 0);
GLuint programId = glCreateProgram();
glAttachShader(programId, vsId);
glAttachShader(programId, fsId);
glBindFragDataLocation(programId, 0, "color");
glLinkProgram(programId);
glDeleteShader(vsId);
glDeleteShader(fsId);
GLint status = GL_FALSE;
glGetProgramiv(programId, GL_LINK_STATUS, &status);
assert(status != GL_FALSE);
return programId;
}
//
struct GLRenderPoints
{
void Create()
{
const char* vs = \
"#version 330\n"
"uniform mat4 projectionMatrix;\n"
"layout(location = 0) in vec2 v_position;\n"
"layout(location = 1) in vec4 v_color;\n"
"layout(location = 2) in float v_size;\n"
"out vec4 f_color;\n"
"void main(void)\n"
"{\n"
" f_color = v_color;\n"
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
" gl_PointSize = v_size;\n"
"}\n";
const char* fs = \
"#version 330\n"
"in vec4 f_color;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = f_color;\n"
"}\n";
m_programId = sCreateShaderProgram(vs, fs);
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
m_vertexAttribute = 0;
m_colorAttribute = 1;
m_sizeAttribute = 2;
// Generate
glGenVertexArrays(1, &m_vaoId);
glGenBuffers(3, m_vboIds);
glBindVertexArray(m_vaoId);
glEnableVertexAttribArray(m_vertexAttribute);
glEnableVertexAttribArray(m_colorAttribute);
glEnableVertexAttribArray(m_sizeAttribute);
// Vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
glVertexAttribPointer(m_sizeAttribute, 1, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_sizes), m_sizes, GL_DYNAMIC_DRAW);
sCheckGLError();
// Cleanup
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
m_count = 0;
}
void Destroy()
{
if (m_vaoId)
{
glDeleteVertexArrays(1, &m_vaoId);
glDeleteBuffers(2, m_vboIds);
m_vaoId = 0;
}
if (m_programId)
{
glDeleteProgram(m_programId);
m_programId = 0;
}
}
void Vertex(const b2Vec2& v, const b2Color& c, float32 size)
{
if (m_count == e_maxVertices)
Flush();
m_vertices[m_count] = v;
m_colors[m_count] = c;
m_sizes[m_count] = size;
++m_count;
}
void Flush()
{
if (m_count == 0)
return;
glUseProgram(m_programId);
float32 proj[16] = { 0.0f };
g_camera.BuildProjectionMatrix(proj, 0.0f);
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, proj);
glBindVertexArray(m_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Vec2), m_vertices);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Color), m_colors);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(float32), m_sizes);
glEnable(GL_PROGRAM_POINT_SIZE);
glDrawArrays(GL_POINTS, 0, m_count);
glDisable(GL_PROGRAM_POINT_SIZE);
sCheckGLError();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
m_count = 0;
}
enum { e_maxVertices = 512 };
b2Vec2 m_vertices[e_maxVertices];
b2Color m_colors[e_maxVertices];
float32 m_sizes[e_maxVertices];
int32 m_count;
GLuint m_vaoId;
GLuint m_vboIds[3];
GLuint m_programId;
GLint m_projectionUniform;
GLint m_vertexAttribute;
GLint m_colorAttribute;
GLint m_sizeAttribute;
};
//
struct GLRenderLines
{
void Create()
{
const char* vs = \
"#version 330\n"
"uniform mat4 projectionMatrix;\n"
"layout(location = 0) in vec2 v_position;\n"
"layout(location = 1) in vec4 v_color;\n"
"out vec4 f_color;\n"
"void main(void)\n"
"{\n"
" f_color = v_color;\n"
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
"}\n";
const char* fs = \
"#version 330\n"
"in vec4 f_color;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = f_color;\n"
"}\n";
m_programId = sCreateShaderProgram(vs, fs);
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
m_vertexAttribute = 0;
m_colorAttribute = 1;
// Generate
glGenVertexArrays(1, &m_vaoId);
glGenBuffers(2, m_vboIds);
glBindVertexArray(m_vaoId);
glEnableVertexAttribArray(m_vertexAttribute);
glEnableVertexAttribArray(m_colorAttribute);
// Vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_DRAW);
sCheckGLError();
// Cleanup
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
m_count = 0;
}
void Destroy()
{
if (m_vaoId)
{
glDeleteVertexArrays(1, &m_vaoId);
glDeleteBuffers(2, m_vboIds);
m_vaoId = 0;
}
if (m_programId)
{
glDeleteProgram(m_programId);
m_programId = 0;
}
}
void Vertex(const b2Vec2& v, const b2Color& c)
{
if (m_count == e_maxVertices)
Flush();
m_vertices[m_count] = v;
m_colors[m_count] = c;
++m_count;
}
void Flush()
{
if (m_count == 0)
return;
glUseProgram(m_programId);
float32 proj[16] = { 0.0f };
g_camera.BuildProjectionMatrix(proj, 0.1f);
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, proj);
glBindVertexArray(m_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Vec2), m_vertices);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Color), m_colors);
glDrawArrays(GL_LINES, 0, m_count);
sCheckGLError();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
m_count = 0;
}
enum { e_maxVertices = 2 * 512 };
b2Vec2 m_vertices[e_maxVertices];
b2Color m_colors[e_maxVertices];
int32 m_count;
GLuint m_vaoId;
GLuint m_vboIds[2];
GLuint m_programId;
GLint m_projectionUniform;
GLint m_vertexAttribute;
GLint m_colorAttribute;
};
//
struct GLRenderTriangles
{
void Create()
{
const char* vs = \
"#version 330\n"
"uniform mat4 projectionMatrix;\n"
"layout(location = 0) in vec2 v_position;\n"
"layout(location = 1) in vec4 v_color;\n"
"out vec4 f_color;\n"
"void main(void)\n"
"{\n"
" f_color = v_color;\n"
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
"}\n";
const char* fs = \
"#version 330\n"
"in vec4 f_color;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = f_color;\n"
"}\n";
m_programId = sCreateShaderProgram(vs, fs);
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
m_vertexAttribute = 0;
m_colorAttribute = 1;
// Generate
glGenVertexArrays(1, &m_vaoId);
glGenBuffers(2, m_vboIds);
glBindVertexArray(m_vaoId);
glEnableVertexAttribArray(m_vertexAttribute);
glEnableVertexAttribArray(m_colorAttribute);
// Vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_DRAW);
sCheckGLError();
// Cleanup
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
m_count = 0;
}
void Destroy()
{
if (m_vaoId)
{
glDeleteVertexArrays(1, &m_vaoId);
glDeleteBuffers(2, m_vboIds);
m_vaoId = 0;
}
if (m_programId)
{
glDeleteProgram(m_programId);
m_programId = 0;
}
}
void Vertex(const b2Vec2& v, const b2Color& c)
{
if (m_count == e_maxVertices)
Flush();
m_vertices[m_count] = v;
m_colors[m_count] = c;
++m_count;
}
void Flush()
{
if (m_count == 0)
return;
glUseProgram(m_programId);
float32 proj[16] = { 0.0f };
g_camera.BuildProjectionMatrix(proj, 0.2f);
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, proj);
glBindVertexArray(m_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Vec2), m_vertices);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Color), m_colors);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLES, 0, m_count);
glDisable(GL_BLEND);
sCheckGLError();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
m_count = 0;
}
enum { e_maxVertices = 3 * 512 };
b2Vec2 m_vertices[e_maxVertices];
b2Color m_colors[e_maxVertices];
int32 m_count;
GLuint m_vaoId;
GLuint m_vboIds[2];
GLuint m_programId;
GLint m_projectionUniform;
GLint m_vertexAttribute;
GLint m_colorAttribute;
};
//
DebugDraw::DebugDraw()
{
m_points = NULL;
m_lines = NULL;
m_triangles = NULL;
}
//
DebugDraw::~DebugDraw()
{
b2Assert(m_points == NULL);
b2Assert(m_lines == NULL);
b2Assert(m_triangles == NULL);
}
//
void DebugDraw::Create()
{
m_points = new GLRenderPoints;
m_points->Create();
m_lines = new GLRenderLines;
m_lines->Create();
m_triangles = new GLRenderTriangles;
m_triangles->Create();
}
//
void DebugDraw::Destroy()
{
m_points->Destroy();
delete m_points;
m_points = NULL;
m_lines->Destroy();
delete m_lines;
m_lines = NULL;
m_triangles->Destroy();
delete m_triangles;
m_triangles = NULL;
}
//
void DebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{
b2Vec2 p1 = vertices[vertexCount - 1];
for (int32 i = 0; i < vertexCount; ++i)
{
b2Vec2 p2 = vertices[i];
m_lines->Vertex(p1, color);
m_lines->Vertex(p2, color);
p1 = p2;
}
}
//
void DebugDraw::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{
b2Color fillColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f);
for (int32 i = 1; i < vertexCount - 1; ++i)
{
m_triangles->Vertex(vertices[0], fillColor);
m_triangles->Vertex(vertices[i], fillColor);
m_triangles->Vertex(vertices[i+1], fillColor);
}
b2Vec2 p1 = vertices[vertexCount - 1];
for (int32 i = 0; i < vertexCount; ++i)
{
b2Vec2 p2 = vertices[i];
m_lines->Vertex(p1, color);
m_lines->Vertex(p2, color);
p1 = p2;
}
}
//
void DebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color)
{
const float32 k_segments = 16.0f;
const float32 k_increment = 2.0f * b2_pi / k_segments;
float32 sinInc = sinf(k_increment);
float32 cosInc = cosf(k_increment);
b2Vec2 r1(1.0f, 0.0f);
b2Vec2 v1 = center + radius * r1;
for (int32 i = 0; i < k_segments; ++i)
{
// Perform rotation to avoid additional trigonometry.
b2Vec2 r2;
r2.x = cosInc * r1.x - sinInc * r1.y;
r2.y = sinInc * r1.x + cosInc * r1.y;
b2Vec2 v2 = center + radius * r2;
m_lines->Vertex(v1, color);
m_lines->Vertex(v2, color);
r1 = r2;
v1 = v2;
}
}
//
void DebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color)
{
const float32 k_segments = 16.0f;
const float32 k_increment = 2.0f * b2_pi / k_segments;
float32 sinInc = sinf(k_increment);
float32 cosInc = cosf(k_increment);
b2Vec2 v0 = center;
b2Vec2 r1(cosInc, sinInc);
b2Vec2 v1 = center + radius * r1;
b2Color fillColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f);
for (int32 i = 0; i < k_segments; ++i)
{
// Perform rotation to avoid additional trigonometry.
b2Vec2 r2;
r2.x = cosInc * r1.x - sinInc * r1.y;
r2.y = sinInc * r1.x + cosInc * r1.y;
b2Vec2 v2 = center + radius * r2;
m_triangles->Vertex(v0, fillColor);
m_triangles->Vertex(v1, fillColor);
m_triangles->Vertex(v2, fillColor);
r1 = r2;
v1 = v2;
}
r1.Set(1.0f, 0.0f);
v1 = center + radius * r1;
for (int32 i = 0; i < k_segments; ++i)
{
b2Vec2 r2;
r2.x = cosInc * r1.x - sinInc * r1.y;
r2.y = sinInc * r1.x + cosInc * r1.y;
b2Vec2 v2 = center + radius * r2;
m_lines->Vertex(v1, color);
m_lines->Vertex(v2, color);
r1 = r2;
v1 = v2;
}
// Draw a line fixed in the circle to animate rotation.
b2Vec2 p = center + radius * axis;
m_lines->Vertex(center, color);
m_lines->Vertex(p, color);
}
//
void DebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
{
m_lines->Vertex(p1, color);
m_lines->Vertex(p2, color);
}
//
void DebugDraw::DrawTransform(const b2Transform& xf)
{
const float32 k_axisScale = 0.4f;
b2Color red(1.0f, 0.0f, 0.0f);
b2Color green(0.0f, 1.0f, 0.0f);
b2Vec2 p1 = xf.p, p2;
m_lines->Vertex(p1, red);
p2 = p1 + k_axisScale * xf.q.GetXAxis();
m_lines->Vertex(p2, red);
m_lines->Vertex(p1, green);
p2 = p1 + k_axisScale * xf.q.GetYAxis();
m_lines->Vertex(p2, green);
}
//
void DebugDraw::DrawPoint(const b2Vec2& p, float32 size, const b2Color& color)
{
m_points->Vertex(p, color, size);
}
//
void DebugDraw::DrawString(int x, int y, const char *string, ...)
{
va_list arg;
va_start(arg, string);
ImGui::Begin("Overlay", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPos(b2Vec2(float(x), float(y)));
ImGui::TextColoredV(ImColor(230, 153, 153, 255), string, arg);
ImGui::End();
va_end(arg);
}
//
void DebugDraw::DrawString(const b2Vec2& pw, const char *string, ...)
{
b2Vec2 ps = g_camera.ConvertWorldToScreen(pw);
va_list arg;
va_start(arg, string);
ImGui::Begin("Overlay", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPos(ps);
ImGui::TextColoredV(ImColor(230, 153, 153, 255), string, arg);
ImGui::End();
va_end(arg);
}
//
void DebugDraw::DrawAABB(b2AABB* aabb, const b2Color& c)
{
b2Vec2 p1 = aabb->lowerBound;
b2Vec2 p2 = b2Vec2(aabb->upperBound.x, aabb->lowerBound.y);
b2Vec2 p3 = aabb->upperBound;
b2Vec2 p4 = b2Vec2(aabb->lowerBound.x, aabb->upperBound.y);
m_lines->Vertex(p1, c);
m_lines->Vertex(p2, c);
m_lines->Vertex(p2, c);
m_lines->Vertex(p3, c);
m_lines->Vertex(p3, c);
m_lines->Vertex(p4, c);
m_lines->Vertex(p4, c);
m_lines->Vertex(p1, c);
}
//
void DebugDraw::Flush()
{
m_triangles->Flush();
m_lines->Flush();
m_points->Flush();
}
/*
* Copyright (c) 2006-2013 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef DEBUGDRAW_H
#define DEBUGDRAW_H
#include "Box2D/Box2D.h"
struct b2AABB;
struct GLRenderPoints;
struct GLRenderLines;
struct GLRenderTriangles;
//
struct Camera
{
Camera()
{
m_center.Set(0.0f, 20.0f);
m_zoom = 1.0f;
m_width = 1280;
m_height = 800;
}
b2Vec2 ConvertScreenToWorld(const b2Vec2& screenPoint);
b2Vec2 ConvertWorldToScreen(const b2Vec2& worldPoint);
void BuildProjectionMatrix(float32* m, float32 zBias);
b2Vec2 m_center;
float32 m_zoom;
int32 m_width;
int32 m_height;
};
// This class implements debug drawing callbacks that are invoked
// inside b2World::Step.
class DebugDraw : public b2Draw
{
public:
DebugDraw();
~DebugDraw();
void Create();
void Destroy();
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) override;
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) override;
void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) override;
void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) override;
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) override;
void DrawTransform(const b2Transform& xf) override;
void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color) override;
void DrawString(int x, int y, const char* string, ...);
void DrawString(const b2Vec2& p, const char* string, ...);
void DrawAABB(b2AABB* aabb, const b2Color& color);
void Flush();
private:
GLRenderPoints* m_points;
GLRenderLines* m_lines;
GLRenderTriangles* m_triangles;
};
extern DebugDraw g_debugDraw;
extern Camera g_camera;
#endif
/*
* Copyright (c) 2006-2016 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <glew/glew.h>
#endif
#include "imgui/imgui.h"
#include "imgui/imgui_impl_glfw_gl3.h"
#include "DebugDraw.h"
#include "Test.h"
#include "glfw/glfw3.h"
#include <stdio.h>
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
// This include was added to support MinGW
#ifdef _WIN32
#include <crtdbg.h>
#endif
//
struct UIState
{
bool showMenu;
};
//
namespace
{
GLFWwindow* mainWindow = NULL;
UIState ui;
int32 testIndex = 0;
int32 testSelection = 0;
int32 testCount = 0;
TestEntry* entry;
Test* test;
Settings settings;
bool rightMouseDown;
b2Vec2 lastp;
}
//
static void sCreateUI(GLFWwindow* window)
{
ui.showMenu = true;
// Init UI
const char* fontPath = "Data/DroidSans.ttf";
ImGui::GetIO().Fonts->AddFontFromFileTTF(fontPath, 15.f);
if (ImGui_ImplGlfwGL3_Init(window, false) == false)
{
fprintf(stderr, "Could not init GUI renderer.\n");
assert(false);
return;
}
ImGuiStyle& style = ImGui::GetStyle();
style.FrameRounding = style.GrabRounding = style.ScrollbarRounding = 2.0f;
style.FramePadding = ImVec2(4, 2);
style.DisplayWindowPadding = ImVec2(0, 0);
style.DisplaySafeAreaPadding = ImVec2(0, 0);
}
//
static void sResizeWindow(GLFWwindow*, int width, int height)
{
g_camera.m_width = width;
g_camera.m_height = height;
}
//
static void sKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
ImGui_ImplGlfwGL3_KeyCallback(window, key, scancode, action, mods);
bool keys_for_ui = ImGui::GetIO().WantCaptureKeyboard;
if (keys_for_ui)
return;
if (action == GLFW_PRESS)
{
switch (key)
{
case GLFW_KEY_ESCAPE:
// Quit
glfwSetWindowShouldClose(mainWindow, GL_TRUE);
break;
case GLFW_KEY_LEFT:
// Pan left
if (mods == GLFW_MOD_CONTROL)
{
b2Vec2 newOrigin(2.0f, 0.0f);
test->ShiftOrigin(newOrigin);
}
else
{
g_camera.m_center.x -= 0.5f;
}
break;
case GLFW_KEY_RIGHT:
// Pan right
if (mods == GLFW_MOD_CONTROL)
{
b2Vec2 newOrigin(-2.0f, 0.0f);
test->ShiftOrigin(newOrigin);
}
else
{
g_camera.m_center.x += 0.5f;
}
break;
case GLFW_KEY_DOWN:
// Pan down
if (mods == GLFW_MOD_CONTROL)
{
b2Vec2 newOrigin(0.0f, 2.0f);
test->ShiftOrigin(newOrigin);
}
else
{
g_camera.m_center.y -= 0.5f;
}
break;
case GLFW_KEY_UP:
// Pan up
if (mods == GLFW_MOD_CONTROL)
{
b2Vec2 newOrigin(0.0f, -2.0f);
test->ShiftOrigin(newOrigin);
}
else
{
g_camera.m_center.y += 0.5f;
}
break;
case GLFW_KEY_HOME:
// Reset view
g_camera.m_zoom = 1.0f;
g_camera.m_center.Set(0.0f, 20.0f);
break;
case GLFW_KEY_Z:
// Zoom out
g_camera.m_zoom = b2Min(1.1f * g_camera.m_zoom, 20.0f);
break;
case GLFW_KEY_X:
// Zoom in
g_camera.m_zoom = b2Max(0.9f * g_camera.m_zoom, 0.02f);
break;
case GLFW_KEY_R:
// Reset test
delete test;
test = entry->createFcn();
break;
case GLFW_KEY_SPACE:
// Launch a bomb.
if (test)
{
test->LaunchBomb();
}
break;
case GLFW_KEY_O:
settings.singleStep = true;
break;
case GLFW_KEY_P:
settings.pause = !settings.pause;
break;
case GLFW_KEY_LEFT_BRACKET:
// Switch to previous test
--testSelection;
if (testSelection < 0)
{
testSelection = testCount - 1;
}
break;
case GLFW_KEY_RIGHT_BRACKET:
// Switch to next test
++testSelection;
if (testSelection == testCount)
{
testSelection = 0;
}
break;
case GLFW_KEY_TAB:
ui.showMenu = !ui.showMenu;
default:
if (test)
{
test->Keyboard(key);
}
}
}
else if (action == GLFW_RELEASE)
{
test->KeyboardUp(key);
}
// else GLFW_REPEAT
}
//
static void sCharCallback(GLFWwindow* window, unsigned int c)
{
ImGui_ImplGlfwGL3_CharCallback(window, c);
}
//
static void sMouseButton(GLFWwindow* window, int32 button, int32 action, int32 mods)
{
ImGui_ImplGlfwGL3_MouseButtonCallback(window, button, action, mods);
double xd, yd;
glfwGetCursorPos(mainWindow, &xd, &yd);
b2Vec2 ps((float32)xd, (float32)yd);
// Use the mouse to move things around.
if (button == GLFW_MOUSE_BUTTON_1)
{
//<##>
//ps.Set(0, 0);
b2Vec2 pw = g_camera.ConvertScreenToWorld(ps);
if (action == GLFW_PRESS)
{
if (mods == GLFW_MOD_SHIFT)
{
test->ShiftMouseDown(pw);
}
else
{
test->MouseDown(pw);
}
}
if (action == GLFW_RELEASE)
{
test->MouseUp(pw);
}
}
else if (button == GLFW_MOUSE_BUTTON_2)
{
if (action == GLFW_PRESS)
{
lastp = g_camera.ConvertScreenToWorld(ps);
rightMouseDown = true;
}
if (action == GLFW_RELEASE)
{
rightMouseDown = false;
}
}
}
//
static void sMouseMotion(GLFWwindow*, double xd, double yd)
{
b2Vec2 ps((float)xd, (float)yd);
b2Vec2 pw = g_camera.ConvertScreenToWorld(ps);
test->MouseMove(pw);
if (rightMouseDown)
{
b2Vec2 diff = pw - lastp;
g_camera.m_center.x -= diff.x;
g_camera.m_center.y -= diff.y;
lastp = g_camera.ConvertScreenToWorld(ps);
}
}
//
static void sScrollCallback(GLFWwindow* window, double dx, double dy)
{
ImGui_ImplGlfwGL3_ScrollCallback(window, dx, dy);
bool mouse_for_ui = ImGui::GetIO().WantCaptureMouse;
if (!mouse_for_ui)
{
if (dy > 0)
{
g_camera.m_zoom /= 1.1f;
}
else
{
g_camera.m_zoom *= 1.1f;
}
}
}
//
static void sRestart()
{
delete test;
entry = g_testEntries + testIndex;
test = entry->createFcn();
}
//
static void sSimulate()
{
glEnable(GL_DEPTH_TEST);
test->Step(&settings);
test->DrawTitle(entry->name);
glDisable(GL_DEPTH_TEST);
if (testSelection != testIndex)
{
testIndex = testSelection;
delete test;
entry = g_testEntries + testIndex;
test = entry->createFcn();
g_camera.m_zoom = 1.0f;
g_camera.m_center.Set(0.0f, 20.0f);
}
}
//
static bool sTestEntriesGetName(void*, int idx, const char** out_name)
{
*out_name = g_testEntries[idx].name;
return true;
}
//
static void sInterface()
{
int menuWidth = 200;
if (ui.showMenu)
{
ImGui::SetNextWindowPos(ImVec2((float)g_camera.m_width - menuWidth - 10, 10));
ImGui::SetNextWindowSize(ImVec2((float)menuWidth, (float)g_camera.m_height - 20));
ImGui::Begin("Testbed Controls", &ui.showMenu, ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoCollapse);
ImGui::PushAllowKeyboardFocus(false); // Disable TAB
ImGui::PushItemWidth(-1.0f);
ImGui::Text("Test");
if (ImGui::Combo("##Test", &testIndex, sTestEntriesGetName, NULL, testCount, testCount))
{
delete test;
entry = g_testEntries + testIndex;
test = entry->createFcn();
testSelection = testIndex;
}
ImGui::Separator();
ImGui::Text("Vel Iters");
ImGui::SliderInt("##Vel Iters", &settings.velocityIterations, 0, 50);
ImGui::Text("Pos Iters");
ImGui::SliderInt("##Pos Iters", &settings.positionIterations, 0, 50);
ImGui::Text("Hertz");
ImGui::SliderFloat("##Hertz", &settings.hz, 5.0f, 120.0f, "%.0f hz");
ImGui::PopItemWidth();
ImGui::Checkbox("Sleep", &settings.enableSleep);
ImGui::Checkbox("Warm Starting", &settings.enableWarmStarting);
ImGui::Checkbox("Time of Impact", &settings.enableContinuous);
ImGui::Checkbox("Sub-Stepping", &settings.enableSubStepping);
ImGui::Separator();
ImGui::Checkbox("Shapes", &settings.drawShapes);
ImGui::Checkbox("Joints", &settings.drawJoints);
ImGui::Checkbox("AABBs", &settings.drawAABBs);
ImGui::Checkbox("Contact Points", &settings.drawContactPoints);
ImGui::Checkbox("Contact Normals", &settings.drawContactNormals);
ImGui::Checkbox("Contact Impulses", &settings.drawContactImpulse);
ImGui::Checkbox("Friction Impulses", &settings.drawFrictionImpulse);
ImGui::Checkbox("Center of Masses", &settings.drawCOMs);
ImGui::Checkbox("Statistics", &settings.drawStats);
ImGui::Checkbox("Profile", &settings.drawProfile);
ImVec2 button_sz = ImVec2(-1, 0);
if (ImGui::Button("Pause (P)", button_sz))
settings.pause = !settings.pause;
if (ImGui::Button("Single Step (O)", button_sz))
settings.singleStep = !settings.singleStep;
if (ImGui::Button("Restart (R)", button_sz))
sRestart();
if (ImGui::Button("Quit", button_sz))
glfwSetWindowShouldClose(mainWindow, GL_TRUE);
ImGui::PopAllowKeyboardFocus();
ImGui::End();
}
//ImGui::ShowTestWindow(NULL);
}
//
void glfwErrorCallback(int error, const char *description)
{
fprintf(stderr, "GLFW error occured. Code: %d. Description: %s\n", error, description);
}
//
int main(int, char**)
{
#if defined(_WIN32)
// Enable memory-leak reports
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
#endif
glfwSetErrorCallback(glfwErrorCallback);
g_camera.m_width = 1024;
g_camera.m_height = 640;
if (glfwInit() == 0)
{
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
char title[64];
sprintf(title, "Box2D Testbed Version %d.%d.%d", b2_version.major, b2_version.minor, b2_version.revision);
#if defined(__APPLE__)
// Without these settings on macOS, OpenGL 2.1 will be used by default which will cause crashes at boot.
// This code is a slightly modified version of the code found here: http://www.glfw.org/faq.html#how-do-i-create-an-opengl-30-context
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
mainWindow = glfwCreateWindow(g_camera.m_width, g_camera.m_height, title, NULL, NULL);
if (mainWindow == NULL)
{
fprintf(stderr, "Failed to open GLFW mainWindow.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(mainWindow);
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
glfwSetScrollCallback(mainWindow, sScrollCallback);
glfwSetWindowSizeCallback(mainWindow, sResizeWindow);
glfwSetKeyCallback(mainWindow, sKeyCallback);
glfwSetCharCallback(mainWindow, sCharCallback);
glfwSetMouseButtonCallback(mainWindow, sMouseButton);
glfwSetCursorPosCallback(mainWindow, sMouseMotion);
glfwSetScrollCallback(mainWindow, sScrollCallback);
#if defined(__APPLE__) == FALSE
//glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
exit(EXIT_FAILURE);
}
#endif
g_debugDraw.Create();
sCreateUI(mainWindow);
testCount = 0;
while (g_testEntries[testCount].createFcn != NULL)
{
++testCount;
}
testIndex = b2Clamp(testIndex, 0, testCount - 1);
testSelection = testIndex;
entry = g_testEntries + testIndex;
test = entry->createFcn();
// Control the frame rate. One draw per monitor refresh.
glfwSwapInterval(1);
double time1 = glfwGetTime();
double frameTime = 0.0;
glClearColor(0.3f, 0.3f, 0.3f, 1.f);
while (!glfwWindowShouldClose(mainWindow))
{
glfwGetWindowSize(mainWindow, &g_camera.m_width, &g_camera.m_height);
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
glViewport(0, 0, bufferWidth, bufferHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ImGui_ImplGlfwGL3_NewFrame();
ImGui::SetNextWindowPos(ImVec2(0,0));
ImGui::SetNextWindowSize(ImVec2((float)g_camera.m_width, (float)g_camera.m_height));
ImGui::Begin("Overlay", NULL, ImVec2(0,0), 0.0f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPos(ImVec2(5, (float)g_camera.m_height - 20));
ImGui::Text("%.1f ms", 1000.0 * frameTime);
ImGui::End();
sSimulate();
sInterface();
// Measure speed
double time2 = glfwGetTime();
double alpha = 0.9f;
frameTime = alpha * frameTime + (1.0 - alpha) * (time2 - time1);
time1 = time2;
ImGui::Render();
glfwSwapBuffers(mainWindow);
glfwPollEvents();
}
if (test)
{
delete test;
test = NULL;
}
g_debugDraw.Destroy();
ImGui_ImplGlfwGL3_Shutdown();
glfwTerminate();
return 0;
}
/*
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "Test.h"
#include <stdio.h>
void DestructionListener::SayGoodbye(b2Joint* joint)
{
if (test->m_mouseJoint == joint)
{
test->m_mouseJoint = NULL;
}
else
{
test->JointDestroyed(joint);
}
}
Test::Test()
{
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
m_world = new b2World(gravity);
m_bomb = NULL;
m_textLine = 30;
m_mouseJoint = NULL;
m_pointCount = 0;
m_destructionListener.test = this;
m_world->SetDestructionListener(&m_destructionListener);
m_world->SetContactListener(this);
m_world->SetDebugDraw(&g_debugDraw);
m_bombSpawning = false;
m_stepCount = 0;
b2BodyDef bodyDef;
m_groundBody = m_world->CreateBody(&bodyDef);
memset(&m_maxProfile, 0, sizeof(b2Profile));
memset(&m_totalProfile, 0, sizeof(b2Profile));
}
Test::~Test()
{
// By deleting the world, we delete the bomb, mouse joint, etc.
delete m_world;
m_world = NULL;
}
void Test::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
const b2Manifold* manifold = contact->GetManifold();
if (manifold->pointCount == 0)
{
return;
}
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints];
b2GetPointStates(state1, state2, oldManifold, manifold);
b2WorldManifold worldManifold;
contact->GetWorldManifold(&worldManifold);
for (int32 i = 0; i < manifold->pointCount && m_pointCount < k_maxContactPoints; ++i)
{
ContactPoint* cp = m_points + m_pointCount;
cp->fixtureA = fixtureA;
cp->fixtureB = fixtureB;
cp->position = worldManifold.points[i];
cp->normal = worldManifold.normal;
cp->state = state2[i];
cp->normalImpulse = manifold->points[i].normalImpulse;
cp->tangentImpulse = manifold->points[i].tangentImpulse;
cp->separation = worldManifold.separations[i];
++m_pointCount;
}
}
void Test::DrawTitle(const char *string)
{
g_debugDraw.DrawString(5, DRAW_STRING_NEW_LINE, string);
m_textLine = 3 * DRAW_STRING_NEW_LINE;
}
class QueryCallback : public b2QueryCallback
{
public:
QueryCallback(const b2Vec2& point)
{
m_point = point;
m_fixture = NULL;
}
bool ReportFixture(b2Fixture* fixture) override
{
b2Body* body = fixture->GetBody();
if (body->GetType() == b2_dynamicBody)
{
bool inside = fixture->TestPoint(m_point);
if (inside)
{
m_fixture = fixture;
// We are done, terminate the query.
return false;
}
}
// Continue the query.
return true;
}
b2Vec2 m_point;
b2Fixture* m_fixture;
};
void Test::MouseDown(const b2Vec2& p)
{
m_mouseWorld = p;
if (m_mouseJoint != NULL)
{
return;
}
// Make a small box.
b2AABB aabb;
b2Vec2 d;
d.Set(0.001f, 0.001f);
aabb.lowerBound = p - d;
aabb.upperBound = p + d;
// Query the world for overlapping shapes.
QueryCallback callback(p);
m_world->QueryAABB(&callback, aabb);
if (callback.m_fixture)
{
b2Body* body = callback.m_fixture->GetBody();
b2MouseJointDef md;
md.bodyA = m_groundBody;
md.bodyB = body;
md.target = p;
md.maxForce = 1000.0f * body->GetMass();
m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
body->SetAwake(true);
}
}
void Test::SpawnBomb(const b2Vec2& worldPt)
{
m_bombSpawnPoint = worldPt;
m_bombSpawning = true;
}
void Test::CompleteBombSpawn(const b2Vec2& p)
{
if (m_bombSpawning == false)
{
return;
}
const float multiplier = 30.0f;
b2Vec2 vel = m_bombSpawnPoint - p;
vel *= multiplier;
LaunchBomb(m_bombSpawnPoint,vel);
m_bombSpawning = false;
}
void Test::ShiftMouseDown(const b2Vec2& p)
{
m_mouseWorld = p;
if (m_mouseJoint != NULL)
{
return;
}
SpawnBomb(p);
}
void Test::MouseUp(const b2Vec2& p)
{
if (m_mouseJoint)
{
m_world->DestroyJoint(m_mouseJoint);
m_mouseJoint = NULL;
}
if (m_bombSpawning)
{
CompleteBombSpawn(p);
}
}
void Test::MouseMove(const b2Vec2& p)
{
m_mouseWorld = p;
if (m_mouseJoint)
{
m_mouseJoint->SetTarget(p);
}
}
void Test::LaunchBomb()
{
b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f);
b2Vec2 v = -5.0f * p;
LaunchBomb(p, v);
}
void Test::LaunchBomb(const b2Vec2& position, const b2Vec2& velocity)
{
if (m_bomb)
{
m_world->DestroyBody(m_bomb);
m_bomb = NULL;
}
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position = position;
bd.bullet = true;
m_bomb = m_world->CreateBody(&bd);
m_bomb->SetLinearVelocity(velocity);
b2CircleShape circle;
circle.m_radius = 0.3f;
b2FixtureDef fd;
fd.shape = &circle;
fd.density = 20.0f;
fd.restitution = 0.0f;
b2Vec2 minV = position - b2Vec2(0.3f,0.3f);
b2Vec2 maxV = position + b2Vec2(0.3f,0.3f);
b2AABB aabb;
aabb.lowerBound = minV;
aabb.upperBound = maxV;
m_bomb->CreateFixture(&fd);
}
void Test::Step(Settings* settings)
{
float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
if (settings->pause)
{
if (settings->singleStep)
{
settings->singleStep = 0;
}
else
{
timeStep = 0.0f;
}
g_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
m_textLine += DRAW_STRING_NEW_LINE;
}
uint32 flags = 0;
flags += settings->drawShapes * b2Draw::e_shapeBit;
flags += settings->drawJoints * b2Draw::e_jointBit;
flags += settings->drawAABBs * b2Draw::e_aabbBit;
flags += settings->drawCOMs * b2Draw::e_centerOfMassBit;
g_debugDraw.SetFlags(flags);
m_world->SetAllowSleeping(settings->enableSleep);
m_world->SetWarmStarting(settings->enableWarmStarting);
m_world->SetContinuousPhysics(settings->enableContinuous);
m_world->SetSubStepping(settings->enableSubStepping);
m_pointCount = 0;
m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations);
m_world->DrawDebugData();
g_debugDraw.Flush();
if (timeStep > 0.0f)
{
++m_stepCount;
}
if (settings->drawStats)
{
int32 bodyCount = m_world->GetBodyCount();
int32 contactCount = m_world->GetContactCount();
int32 jointCount = m_world->GetJointCount();
g_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints = %d/%d/%d", bodyCount, contactCount, jointCount);
m_textLine += DRAW_STRING_NEW_LINE;
int32 proxyCount = m_world->GetProxyCount();
int32 height = m_world->GetTreeHeight();
int32 balance = m_world->GetTreeBalance();
float32 quality = m_world->GetTreeQuality();
g_debugDraw.DrawString(5, m_textLine, "proxies/height/balance/quality = %d/%d/%d/%g", proxyCount, height, balance, quality);
m_textLine += DRAW_STRING_NEW_LINE;
}
// Track maximum profile times
{
const b2Profile& p = m_world->GetProfile();
m_maxProfile.step = b2Max(m_maxProfile.step, p.step);
m_maxProfile.collide = b2Max(m_maxProfile.collide, p.collide);
m_maxProfile.solve = b2Max(m_maxProfile.solve, p.solve);
m_maxProfile.solveInit = b2Max(m_maxProfile.solveInit, p.solveInit);
m_maxProfile.solveVelocity = b2Max(m_maxProfile.solveVelocity, p.solveVelocity);
m_maxProfile.solvePosition = b2Max(m_maxProfile.solvePosition, p.solvePosition);
m_maxProfile.solveTOI = b2Max(m_maxProfile.solveTOI, p.solveTOI);
m_maxProfile.broadphase = b2Max(m_maxProfile.broadphase, p.broadphase);
m_totalProfile.step += p.step;
m_totalProfile.collide += p.collide;
m_totalProfile.solve += p.solve;
m_totalProfile.solveInit += p.solveInit;
m_totalProfile.solveVelocity += p.solveVelocity;
m_totalProfile.solvePosition += p.solvePosition;
m_totalProfile.solveTOI += p.solveTOI;
m_totalProfile.broadphase += p.broadphase;
}
if (settings->drawProfile)
{
const b2Profile& p = m_world->GetProfile();
b2Profile aveProfile;
memset(&aveProfile, 0, sizeof(b2Profile));
if (m_stepCount > 0)
{
float32 scale = 1.0f / m_stepCount;
aveProfile.step = scale * m_totalProfile.step;
aveProfile.collide = scale * m_totalProfile.collide;
aveProfile.solve = scale * m_totalProfile.solve;
aveProfile.solveInit = scale * m_totalProfile.solveInit;
aveProfile.solveVelocity = scale * m_totalProfile.solveVelocity;
aveProfile.solvePosition = scale * m_totalProfile.solvePosition;
aveProfile.solveTOI = scale * m_totalProfile.solveTOI;
aveProfile.broadphase = scale * m_totalProfile.broadphase;
}
g_debugDraw.DrawString(5, m_textLine, "step [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.step, aveProfile.step, m_maxProfile.step);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "collide [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.collide, aveProfile.collide, m_maxProfile.collide);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "solve [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solve, aveProfile.solve, m_maxProfile.solve);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "solve init [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveInit, aveProfile.solveInit, m_maxProfile.solveInit);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "solve velocity [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveVelocity, aveProfile.solveVelocity, m_maxProfile.solveVelocity);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "solve position [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solvePosition, aveProfile.solvePosition, m_maxProfile.solvePosition);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "solveTOI [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveTOI, aveProfile.solveTOI, m_maxProfile.solveTOI);
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "broad-phase [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.broadphase, aveProfile.broadphase, m_maxProfile.broadphase);
m_textLine += DRAW_STRING_NEW_LINE;
}
if (m_mouseJoint)
{
b2Vec2 p1 = m_mouseJoint->GetAnchorB();
b2Vec2 p2 = m_mouseJoint->GetTarget();
b2Color c;
c.Set(0.0f, 1.0f, 0.0f);
g_debugDraw.DrawPoint(p1, 4.0f, c);
g_debugDraw.DrawPoint(p2, 4.0f, c);
c.Set(0.8f, 0.8f, 0.8f);
g_debugDraw.DrawSegment(p1, p2, c);
}
if (m_bombSpawning)
{
b2Color c;
c.Set(0.0f, 0.0f, 1.0f);
g_debugDraw.DrawPoint(m_bombSpawnPoint, 4.0f, c);
c.Set(0.8f, 0.8f, 0.8f);
g_debugDraw.DrawSegment(m_mouseWorld, m_bombSpawnPoint, c);
}
if (settings->drawContactPoints)
{
const float32 k_impulseScale = 0.1f;
const float32 k_axisScale = 0.3f;
for (int32 i = 0; i < m_pointCount; ++i)
{
ContactPoint* point = m_points + i;
if (point->state == b2_addState)
{
// Add
g_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
}
else if (point->state == b2_persistState)
{
// Persist
g_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
}
if (settings->drawContactNormals == 1)
{
b2Vec2 p1 = point->position;
b2Vec2 p2 = p1 + k_axisScale * point->normal;
g_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f));
}
else if (settings->drawContactImpulse == 1)
{
b2Vec2 p1 = point->position;
b2Vec2 p2 = p1 + k_impulseScale * point->normalImpulse * point->normal;
g_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
}
if (settings->drawFrictionImpulse == 1)
{
b2Vec2 tangent = b2Cross(point->normal, 1.0f);
b2Vec2 p1 = point->position;
b2Vec2 p2 = p1 + k_impulseScale * point->tangentImpulse * tangent;
g_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
}
}
}
}
void Test::ShiftOrigin(const b2Vec2& newOrigin)
{
m_world->ShiftOrigin(newOrigin);
}