root/OpenSceneGraph/trunk/src/osgParticle/BounceOperator.cpp @ 13041

Revision 13041, 6.0 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13// Written by Wang Rui, (C) 2010
14
15#include <osg/Notify>
16#include <osgParticle/ModularProgram>
17#include <osgParticle/BounceOperator>
18
19using namespace osgParticle;
20
21void BounceOperator::handleTriangle( const Domain& domain, Particle* P, double dt )
22{
23    osg::Vec3 nextpos = P->getPosition() + P->getVelocity() * dt;
24    float distance = domain.plane.distance( P->getPosition() );
25    if ( distance*domain.plane.distance(nextpos)>=0 ) return;
26
27    osg::Vec3 normal = domain.plane.getNormal();
28    float nv = normal * P->getVelocity();
29    osg::Vec3 hitPoint = P->getPosition() - P->getVelocity() * (distance / nv);
30
31    float upos = (hitPoint - domain.v1) * domain.s1;
32    float vpos = (hitPoint - domain.v1) * domain.s2;
33    if ( upos<0.0f || vpos<0.0f || (upos + vpos)>1.0f ) return;
34
35    // Compute tangential and normal components of velocity
36    osg::Vec3 vn = normal * nv;
37    osg::Vec3 vt = P->getVelocity() - vn;
38
39    // Compute new velocity
40    if ( vt.length2()<=_cutoff ) P->setVelocity( vt - vn*_resilience );
41    else P->setVelocity( vt*(1.0f-_friction) - vn*_resilience );
42}
43
44void BounceOperator::handleRectangle( const Domain& domain, Particle* P, double dt )
45{
46    osg::Vec3 nextpos = P->getPosition() + P->getVelocity() * dt;
47    float distance = domain.plane.distance( P->getPosition() );
48    if ( distance*domain.plane.distance(nextpos)>=0 ) return;
49
50    osg::Vec3 normal = domain.plane.getNormal();
51    float nv = normal * P->getVelocity();
52    osg::Vec3 hitPoint = P->getPosition() - P->getVelocity() * (distance / nv);
53
54    float upos = (hitPoint - domain.v1) * domain.s1;
55    float vpos = (hitPoint - domain.v1) * domain.s2;
56    if ( upos<0.0f || upos>1.0f || vpos<0.0f || vpos>1.0f ) return;
57
58    // Compute tangential and normal components of velocity
59    osg::Vec3 vn = normal * nv;
60    osg::Vec3 vt = P->getVelocity() - vn;
61
62    // Compute new velocity
63    if ( vt.length2()<=_cutoff ) P->setVelocity( vt - vn*_resilience );
64    else P->setVelocity( vt*(1.0f-_friction) - vn*_resilience );
65}
66
67void BounceOperator::handlePlane( const Domain& domain, Particle* P, double dt )
68{
69    osg::Vec3 nextpos = P->getPosition() + P->getVelocity() * dt;
70    float distance = domain.plane.distance( P->getPosition() );
71    if ( distance*domain.plane.distance(nextpos)>=0 ) return;
72
73    osg::Vec3 normal = domain.plane.getNormal();
74    float nv = normal * P->getVelocity();
75
76    // Compute tangential and normal components of velocity
77    osg::Vec3 vn = normal * nv;
78    osg::Vec3 vt = P->getVelocity() - vn;
79
80    // Compute new velocity
81    if ( vt.length2()<=_cutoff ) P->setVelocity( vt - vn*_resilience );
82    else P->setVelocity( vt*(1.0f-_friction) - vn*_resilience );
83}
84
85void BounceOperator::handleSphere( const Domain& domain, Particle* P, double dt )
86{
87    osg::Vec3 nextpos = P->getPosition() + P->getVelocity() * dt;
88    float distance1 = (P->getPosition() - domain.v1).length();
89    if ( distance1<=domain.r1 )  // Within the sphere
90    {
91        float distance2 = (nextpos - domain.v1).length();
92        if ( distance2<=domain.r1 ) return;
93
94        // Bounce back in if going outside
95        osg::Vec3 normal = domain.v1 - P->getPosition(); normal.normalize();
96        float nmag = P->getVelocity() * normal;
97
98        // Compute tangential and normal components of velocity
99        osg::Vec3 vn = normal * nmag;
100        osg::Vec3 vt = P->getVelocity() - vn;
101        if ( nmag<0 ) vn = -vn;
102
103        // Compute new velocity
104        float tanscale = (vt.length2()<=_cutoff) ? 1.0f : (1.0f - _friction);
105        P->setVelocity( vt * tanscale + vn * _resilience );
106
107        // Make sure the particle is fixed to stay inside
108        nextpos = P->getPosition() + P->getVelocity() * dt;
109        distance2 = (nextpos - domain.v1).length();
110        if ( distance2>domain.r1 )
111        {
112            normal = domain.v1 - nextpos; normal.normalize();
113
114            osg::Vec3 wishPoint = domain.v1 - normal * (0.999f * domain.r1);
115            P->setVelocity( (wishPoint - P->getPosition()) / dt );
116        }
117    }
118    else  // Outside the sphere
119    {
120        float distance2 = (nextpos - domain.v1).length();
121        if ( distance2>domain.r1 ) return;
122
123        // Bounce back out if going inside
124        osg::Vec3 normal = P->getPosition() - domain.v1; normal.normalize();
125        float nmag = P->getVelocity() * normal;
126
127        // Compute tangential and normal components of velocity
128        osg::Vec3 vn = normal * nmag;
129        osg::Vec3 vt = P->getVelocity() - vn;
130        if ( nmag<0 ) vn = -vn;
131
132        // Compute new velocity
133        float tanscale = (vt.length2()<=_cutoff) ? 1.0f : (1.0f - _friction);
134        P->setVelocity( vt * tanscale + vn * _resilience );
135    }
136}
137
138void BounceOperator::handleDisk( const Domain& domain, Particle* P, double dt )
139{
140    osg::Vec3 nextpos = P->getPosition() + P->getVelocity() * dt;
141    float distance = domain.plane.distance( P->getPosition() );
142    if ( distance*domain.plane.distance(nextpos)>=0 ) return;
143
144    osg::Vec3 normal = domain.plane.getNormal();
145    float nv = normal * P->getVelocity();
146    osg::Vec3 hitPoint = P->getPosition() - P->getVelocity() * (distance / nv);
147
148    float radius = (hitPoint - domain.v1).length();
149    if ( radius>domain.r1 || radius<domain.r2 ) return;
150
151    // Compute tangential and normal components of velocity
152    osg::Vec3 vn = normal * nv;
153    osg::Vec3 vt = P->getVelocity() - vn;
154
155    // Compute new velocity
156    if ( vt.length2()<=_cutoff ) P->setVelocity( vt - vn*_resilience );
157    else P->setVelocity( vt*(1.0f-_friction) - vn*_resilience );
158}
Note: See TracBrowser for help on using the browser.