Silas Marner
by George Eliot
Part 2, Chapter 21
Additional Information
- Year Published: 1861
- Language: English
- Country of Origin: England
- Source: Eliot, G. (1861). Silas Marner. London, England: William Blackwood and Sons.
-
Readability:
- Flesch–Kincaid Level: 12.0
- Word Count: 1,469
- Genre: Realism
- Keywords: 19th century literature, british literature
- ✎ Cite This
Downloads
The next morning, when Silas and Eppie were seated at their breakfast, he said to her—
"Eppie, there's a thing I've had on my mind to do this two year, and now the money's been brought back to us, we can do it. I've been turning it over and over in the night, and I think we'll set out to–morrow, while the fine days last. We'll leave the house and everything for your godmother to take care on, and we'll make a little bundle o' things and set out."
"Where to go, daddy?" said Eppie, in much surprise.
"To my old country—to the town where I was born—up Lantern Yard. I want to see Mr. Paston, the minister: something may ha' come out to make 'em know I was innicent o' the robbery. And Mr. Paston was a man with a deal o' light—I want to speak to him about the drawing o' the lots. And I should like to talk to him about the religion o' this country–side, for I partly think he doesn't know on it."
Eppie was very joyful, for there was the prospect not only of wonder and delight at seeing a strange country, but also of coming back to tell Aaron all about it. Aaron was so much wiser than she was about most things—it would be rather pleasant to have this little advantage over him. Mrs. Winthrop, though possessed with a dim fear of dangers attendant on so long a journey, and requiring many assurances that it would not take them out of the region of carriers' carts and slow waggons, was nevertheless well pleased that Silas should revisit his own country, and find out if he had been cleared from that false accusation.
 And if there's any light to be got up the yard as you talk on, we've need of it i' this world, and I'd be glad on it myself, if you could bring it back."
So on the fourth day from that time, Silas and Eppie, in their Sunday clothes, with a small bundle tied in a blue linen handkerchief, were making their way through the streets of a great manufacturing town. Silas, bewildered by the changes thirty years had brought over his native place, had stopped several persons in succession to ask them the name of this town, that he might be sure he was not under a mistake about it.
"Ask for Lantern Yard, father—ask this gentleman with the tassels on his shoulders a–standing at the shop door; he isn't in a hurry like the rest," said Eppie, in some distress at her father's bewilderment, and ill at ease, besides, amidst the noise, the movement, and the multitude of strange indifferent faces.
"Eh, my child, he won't know anything about it," said Silas; "gentlefolks didn't ever go up the Yard. But happen somebody can tell me which is the way to Prison Street, where the jail is. I know the way out o' that as if I'd seen it yesterday."
With some difficulty, after many turnings and new inquiries, they reached Prison Street; and the grim walls of the jail, the first object that answered to any image in Silas's memory, cheered him with the certitude, which no assurance of the town's name had hitherto given him, that he was in his native place.
"Ah," he said, drawing a long breath, "there's the jail, Eppie; that's just the same: I aren't afraid now. It's the third turning on the left hand from the jail doors—that's the way we must go."
 said Eppie. "How it hides the sky! It's worse than the Workhouse. I'm glad you don't live in this town now, father. Is Lantern Yard like this street?"
"My precious child," said Silas, smiling, "it isn't a big street like this. I never was easy i' this street myself, but I was fond o' Lantern Yard. The shops here are all altered, I think—I can't make 'em out; but I shall know the turning, because it's the third."
"Here it is," he said, in a tone of satisfaction, as they came to a narrow alley. "And then we must go to the left again, and then straight for'ard for a bit, up Shoe Lane: and then we shall be at the entry next to the o'erhanging window, where there's the nick in the road for the water to run. Eh, I can see it all."
"O father, I'm like as if I was stifled," said Eppie. "I couldn't ha' thought as any folks lived i' this way, so close together. How pretty the Stone–pits 'ull look when we get back!"
"It looks comical to me, child, now—and smells bad. I can't think as it usened to smell so."
Here and there a sallow, begrimed face looked out from a gloomy doorway at the strangers, and increased Eppie's uneasiness, so that it was a longed–for relief when they issued from the alleys into Shoe Lane, where there was a broader strip of sky.
"Dear heart!" said Silas, "why, there's people coming out o' the Yard as if they'd been to chapel at this time o' day—a weekday noon!"
Suddenly he started and stood still with a look of distressed amazement, that alarmed Eppie. They were before an opening in front of a large factory, from which men and women were streaming for their midday meal.
"Father," said Eppie, clasping his arm, "what's the matter?"
But she had to speak again and again before Silas could answer her.
"It's gone, child," he said, at last, in strong agitation—"Lantern Yard's gone. It must ha' been here, because here's the house with the o'erhanging window—I know that—it's just the same; but they've made this new opening; and see that big factory! It's all gone—chapel and all."
 "Perhaps the people can tell you all about it."
But neither from the brush–maker, who had come to Shoe Lane only ten years ago, when the factory was already built, nor from any other source within his reach, could Silas learn anything of the old Lantern Yard friends, or of Mr. Paston the minister.
"The old place is all swep' away," Silas said to Dolly Winthrop on the night of his return—"the little graveyard and everything. The old home's gone; I've no home but this now. I shall never know whether they got at the truth o' the robbery, nor whether Mr. Paston could ha' given me any light about the drawing o' the lots. It's dark to me, Mrs. Winthrop, that is; I doubt it'll be dark to the last."
"Well, yes, Master Marner," said Dolly, who sat with a placid listening face, now bordered by grey hairs; "I doubt it may. It's the will o' Them above as a many things should be dark to us; but there's some things as I've never felt i' the dark about, and they're mostly what comes i' the day's work. You were hard done by that once, Master Marner, and it seems as you'll never know the rights of it; but that doesn't hinder there being a rights, Master Marner, for all it's dark to you and me."
"No," said Silas, "no; that doesn't hinder. Since the time the child was sent to me and I've come to love her as myself, I've had light enough to trusten by; and now she says she'll never leave me, I think I shall trusten till I die."


Files CCore/inc/base/Quick.h CCore/src/base/Quick.cpp CCore/src/base/Quick.s
This part contains some "quick" functions. These functions may use hardware capabilities to accelerate its operations.
#ifndef CCore_inc_base_Quick_h #define CCore_inc_base_Quick_h #include <CCore/inc/base/PlatformBase.h> namespace CCore { namespace Quick { /* consts */ inline constexpr bool ScanLSBitIsFast = false ; inline constexpr bool ScanMSBitIsFast = false ; /* types */ using ScanUInt = .... ; // unsigned integral type /* functions */ unsigned ScanLSBit(ScanUInt value) noexcept; unsigned ScanMSBit(ScanUInt value) noexcept; uint16 ByteSwap16(uint16 value) noexcept; uint32 ByteSwap32(uint32 value) noexcept; uint64 ByteSwap64(uint64 value) noexcept; /* classes */ template <unsigned UIntBits> struct UIntMulSelectCtor; template <class UInt> struct UIntMulFunc; /* struct UIntMulSelectCtor<unsigned UIntBits> */ template <> struct UIntMulSelectCtor<8> { using Ret = uint16 ; }; template <> struct UIntMulSelectCtor<16> { using Ret = uint32 ; }; template <> struct UIntMulSelectCtor<32> { using Ret = uint32 ; }; template <> struct UIntMulSelectCtor<64> { using Ret = uint64 ; }; /* type UIntMulSelect<unsigned UIntBits> */ template <unsigned UIntBits> using UIntMulSelect = typename UIntMulSelectCtor<UIntBits>::Ret ; /* struct UIntMulFunc<uint32> */ template <> struct UIntMulFunc<uint32> { using UInt = uint32 ; struct Mul { UInt hi; UInt lo; Mul(UInt a,UInt b); }; static UInt Div(UInt hi,UInt lo,UInt den); // hi<den static UInt Mod(UInt hi,UInt lo,UInt den); // hi<den static UInt MulDiv(UInt a,UInt b,UInt den); // hi(a*b)<den struct DivMod { UInt div; UInt mod; DivMod(UInt hi,UInt lo,UInt den); // hi<den }; static UInt ModMul(UInt a,UInt b,UInt mod); // a,b < mod static UInt ModMac(UInt s,UInt a,UInt b,UInt mod); // s,a,b < mod }; /* struct UIntMulFunc<uint64> */ template <> struct UIntMulFunc<uint64> { using UInt = uint64 ; struct Mul { UInt hi; UInt lo; Mul(UInt a,UInt b); }; static UInt Div(UInt hi,UInt lo,UInt den); // hi<den static UInt Mod(UInt hi,UInt lo,UInt den); // hi<den static UInt MulDiv(UInt a,UInt b,UInt den); // hi(a*b)<den struct DivMod { UInt div; UInt mod; DivMod(UInt hi,UInt lo,UInt den); // hi<den }; static UInt ModMul(UInt a,UInt b,UInt mod); // a,b < mod static UInt ModMac(UInt s,UInt a,UInt b,UInt mod); // s,a,b < mod }; } // namespace Quick } // namespace CCore #endif
ScanLSBit() scans the argument for the less significant bit equals 1 and returns its number (bits are numbered from LSB to MSB).
ScanMSBit() scans the argument for the most significant bit equals 1 and returns its number (bits are numbered from LSB to MSB).
Both scan functions operate on the argument of the type ScanUInt, which must be an unsigned integral type. If the argument is null, the return value is not specified. Flags ScanLSBitIsFast and ScanMSBitIsFast are set, if the correspondent function has a fast implementation. The type ScanUInt should be a machine word size type, the wider it is the better.
ByteSwap16() swaps the bytes of the argument and returns the result. I.e. if the argument consists of the bytes (b0,b1), then the result is (b1,b0).
ByteSwap32() swaps the bytes of the argument and returns the result. I.e. if the argument consists of the bytes (b0,b1,b2,b3), then the result is (b3,b2,b1,b0).
ByteSwap64() swaps the bytes of the argument and returns the result. I.e. if the argument consists of the bytes (b0,b1,b2,b3,b4,b5,b6,b7), then the result is (b7,b6,b5,b4,b3,b2,b1,b0).
The rest is to support integer multiplicative operations. This is done using the Meta-Type UIntMulSelect and the structure template UIntMulFunc. These structures are not defined itself, but its specializations must be given.
UIntMulSelect must be specialized for the four following values: 8, 16, 32, 64 as following:
template <>
struct UIntMulSelectCtor<N>
{
using Ret = .... ; // unsigned integral type
};
template <unsigned UIntBits>
using UIntMulSelect = typename UIntMulSelectCtor<UIntBits>::Ret ;
Ret is some unsigned integral type. Either this type has the bit width greater or equal than 2*N, or Ret is the N-bit unsigned integral type. In the first case extended multiplicative operations for the type uintN are implemented using the operations on the type Ret. Otherwise the specialization UIntMulFunc<uintN> must be given. Such specialization must provide the following:
template <> struct UIntMulFunc<uintN> { using UInt = uintN ; struct Mul { UInt hi; UInt lo; Mul(UInt a,UInt b); }; static UInt Div(UInt hi,UInt lo,UInt den); // hi<den static UInt Mod(UInt hi,UInt lo,UInt den); // hi<den static UInt MulDiv(UInt a,UInt b,UInt den); // hi(a*b)<den struct DivMod { UInt div; UInt mod; DivMod(UInt hi,UInt lo,UInt den); // hi<den }; static UInt ModMul(UInt a,UInt b,UInt mod); // a,b < mod static UInt ModMac(UInt s,UInt a,UInt b,UInt mod); // s,a,b < mod };
Mul() performs the full multiplication of the arguments a and b and returns the result in the pair hi and lo, where hi is the high part of the product and the lo is the lower part of the product.
Div() performs the division of the double-size value, given by the arguments hi and lo, by the third argument den. It is assumed, that hi < den, in such case the result is represented by the single-size value. Otherwise the behavior is unspecified (it may cause hardware trap).
Mod() calculates the remainder of the division of the double-size value, given by the arguments hi and lo, by the third argument den. It is assumed, that hi < den. Otherwise the behavior is unspecified (it may cause hardware trap).
MulDiv() multiplies a and b and divides the full double-size product by den. The high part of the product must be less than den, otherwise the behavior is unspecified (it may cause hardware trap).
DivMod() performs both operations Div() and Mod() and returns the result in the fields div and mod.
ModMul() calculates the product of the a and b by the module mod. It is assumed, that a and b < mod, otherwise the behavior is unspecified (it may cause hardware trap). The result is less than mod.
ModMac() calculates the expression s+a*b by the module mod. It is assumed, that a, b and s < mod, otherwise the behavior is unspecified (it may cause hardware trap). The result is less than mod.


{% include "nav.html" %}
Password Reset Form
Please enter your new password so we can verify.
{% csrf_token %} {{form}}
{% include "footer.html" %}


-
Marine Biology
by Ritapa Neogi on June 25, 2017
If we were entirely made by thread, I’d be the red yarn.
There is something about rods and cones
that doesn’t seem to like danger. They work like facets on diamonds,
sample lipstick at the grocery, white letters on stop signs;
like the word “caramel” when I say it.
God, I just want to be important. I just want to be someone real.
The early autumn leaves have me thinking deep crimson hue is only okay
when it’s fifty miles early and I should’ve expected it.
What’s the fun in being real when you have to prove it? Let’s see,
I have a dog. When I was four I stepped on a nail and had it taken out with tweezers;
when I was seventeen I glued cigarettes into scrapbooks.  Sometimes,
I sit in bed and wonder how to shed eyelashes
and the effects of antidepressants on women taking birth control.

I’m waiting for you to stare at the sea ‘til you’re positive there’s something there.
Under all these deeply damaged layers of artificial material and cheaply-crafted plastic,
there’s something there, and I can’t believe it’d take a bachelor’s degree to see it.
-
i’d like to wrap you in saran wrap and save you for dinner tomorrow night
by Sara Martin on May 4, 2017
there are subtle sweaters my mind knits you.
they are purple when you walk
red when you take your shoes off
when i find printed socks i weave them in,
and drip sweet old sesame oil between the hairs and the knit.
there are subtle sweaters my teeth build you,
after i brush them too,
when i don’t speak and it’s mostly in february
what is it about the letters f ‘ruary’
that squeezes in love
through the cushions?
-
The Bees
by Carl Boon on May 1, 2017
Already in August the bees
had gone to ground,
burrowing for rain.
Already we knew
many things of winter,
the frozen doorsteps,
the slush on Third Street.
The mower’s blade,
unsharpened since my father’s death,
startled two who rose and stung—
the light of pain, the annoying
thought that I was wrong—
being there, a blaze
of flesh, a man.
We have our flannel
and our heated rooms,
hot water and the hour of sleep
before we leap
into the day, things to fracture
and collect, things to heed.
The bees are still, memorial,
the winds of Illinois
only they can hear.
Already they knew
in August the squalls of snow
off Lake Erie, the dents
men make
as they perfect the land.
-
god is a 12 year old girl
by Angie Sijun Lou on April 26, 2017
It’s night one of Aquarius season
& the road is bleached with moon
& spit. I’m looking at my bangs
crusted like a helmet to my face.
I’m looking to kill the president
of the USA—if not the tower, the
hallway, if not his ghost, his hands.

I told him god is a 12 year old girl
leaking all her hidden bitter tears
on a kitchen table.
When I was 12 a nice white lady
mistook me for her adopted
daughter every day after school.
 My
mom doesn’t believe in abortions
so she mailed me to Shanghai with
a suitcase filled with breastmilk
as soon as I was born. There are no
stars in the womb but the stars in
Amerika glimmer like cruel babies
in the rain.
Last night I dreamt of a wet block
of tofu falling down an escalator,
step by step, into a shallow eternity.
I know it meant nothing but it went
on all night long. At the end of this
escalator I witnessed god sitting
at a kitchen table.


Arrays vs. Hashes
How Ruby Contains Lists of Values
February 15th, 2016
Ruby has two different containers of data that are called upon regularly and these are arrays and hashes. Both of them can be described as indexed collections with a key and corresponding value, however they each act a little differently as we will see below.
Arrays are an ordered list where each value inside is called upon with a corresponding key that is a numbered index position. The array is displayed in ruby as a list of things, inside a bracket, each value seperated by a comma like so: "array_list = [value1, value2, value3]". The corresponding indexed position begins with 0, so "value1" is actually in the 0 position and not the 1 position. So if you wanted to target just the first value (value1) you would type in "array_list[0]" and then add 1 for the next corresponding position. So then 0 is the array key for "value1". When I say a list of things, the things can be mostly any ruby value such as a string, an integer, a float or even another array.
It can be argued that it is more efficient to use arrays over hashes for the most part but not when you want a little more flexibility with your keys. A hash is displayed very similarly to an array but instead of brackets we use those fancy little curly bracers { }. Also unique to hashes is that the key is actually found inside the bracers along with their corresponding values like so: "basic_hash = {"Name" => "Ryan", "Location" => "California", "Age" => "Nice try"}. So here we see hashes have unique keys defined with unique corresponding values. Once the key is defined, you just have to call upon it's value using the unique corresponding key like you did with arrays using index positions: 'basic_hash["Location"] => "California"'


free delivery & free returns
shop your nearest store
Shop
About
Cart
Account
Search
My Jacket, My Way
Whatever you’re up to this season, we’ve got the jackets and coats to see you through.
#SDMYWAY
Shop Men
Shop Women


A lot of funny things probably go on backstage at any given beauty contest, but obviously writer Lona Williams never heard about any of them. Instead of offering any kind of juicy details -- we all knew about how contestants put Vaseline on their teeth to brighten their smiles, thank you -- her screenplay for "Drop Dead Gorgeous" merely trots out a bunch of cliched characters, saddles them with Minnesota acents and expects hilarity to follow.
With its conniving mothers and star-struck daughters, "Gorgeous" begs unflattering comparisons to two other similar and far superior films, both directed by Michael Ritchie. His outrageously funny "Smile" stands as the last word on teen pageants, while his "The Positively True Alleged Texas Cheerleader-Murdering Mom," a 1993 HBO movie starring Holly Hunter as the kook who went to prison for attempting to hire killers to ensure her kid made the cheerleading squad, had an edginess and spark that's nowhere to be found here.
Clumsily directed by Michael Patrick Jann, "Gorgeous" offers a mock-documentary look at what happens when girls from the opposite sides of the social scale compete for the title of Sarah Rose Cosmetics American Teen Princess. Rebecca Leeman (Denise Richards) is a well-to-do beauty whose dad owns a furniture store, while Amber Atkins (Kirsten Dunst) works afterschool as a beautician in a funeral home to help pay the bills. Rebecca's mom Gladys (a tired-looking Kirstie Alley) is snippy and snobbish; Amber's mom Annette (Ellen Barkin, in yet another role unworthy of her) is crude and boozy. Williams, from the evidence onscreen, never met a stereotype she couldn't embrace.
But it's not a crime to use stereotypes in a comedy if you can find something amusing for them to say, as David E. Kelley did in "Lake Placid." Williams, however, thinks we should be tickled just by the mere mention of cow-tipping, lutefisk and Melissa Manchester. At one point, fire sweeps through the Atkins' trailer and Amber reports all their clothes "melted together, forming a big polyester meteor in our closet." Poor people living in trailer parks and wearing polyester -- pretty witty stuff, this.
In some kind of attempt to top "There's Something About Mary," "Gorgeous" also includes a mentally challenged character who bumps into things and plays with himself in front of the contestants. It also makes several slaps at Lutherans, with an organization called the Lutheran Sisterhood Gun Club and a joke about the Lutheran church being holier the Catholic church because "Lutherans use grape Kool-Aid for the blood of Christ."
Lost in this mess are a couple of respectable performances by Richards and Dunst, the only people in the movie who seem to understand that playing comedy does not mean you have to shout frequently and exaggerate every gesture. Dunst, remembered as the creepy child from "Interview With the Vampire," has turned into a highly likable young actress, and Richards is spotlighted in one of the film's few funny scenes, a bizarre moment involving a Frankie Valli song and an effigy of Jesus Christ. Most of the rest of "Drop Dead Gorgeous" simply falls flat.
James Sanford
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


First of all, Chipmunk is a 2D rigid body physics library distributed under the MIT license. It is intended to be fast, portable, numerically stable, and easy to use. For this reason it’s been used in hundreds of games on every system you can name. This includes top quality titles such as Night Sky for the Wii and many #1 sellers on the iPhone App Store! I’ve put thousands of hours of work over many years to make Chipmunk what it is today. If you find Chipmunk has saved you a lot of time, please consider donating. You’ll make an indie game developer very happy!
First of all, I would like to give a Erin Catto a big thank you, as Chipmunk’s impulse solver was directly inspired by his Box2D example code way back in 2006. (Now a full fledged physics engine all it’s own: Box2D.org). His contact persistence idea allows for stable stacks of objects with very few iterations of the solver. My previous solver produced mushy piles of objects or required a large amount of CPU to operate stably.
A lot of people ask me why I wrote Chipmunk in C instead of pick your favorite language here. I tend to get really excited about different programming languages. Depending on the month, take your pick of Scheme, OCaml, Ruby, Objective-C, OOC, Lua, Io… the list goes on. The one common factor between most any language is that they are usually dead simple to make bindings to C code. I wanted Chipmunk to be fast, portable, and easy to optimize. With Chipmunk weiging in at less than 7,500 lines of C code, headers and comments, I don’t feel that using C has made Chipmunk difficult to develop. In fact, at times I feel it has made it easier to optimize and debug.
That said, I’ve never developed a whole game in C and I probably never will. There are much more interesting languages to do that in than C with all sorts of nice features like garbage collection, closures and object oriented runtimes. Check out the Bindings and Ports page to see if you can use Chipmunk from your language of choice. Because Chipmunk is written in a subset of C99 it compiles cleanly as C, C++, Objective-C and Objective-C++ code, making it easy to integrate into projects in those languages.
If you are writing iPhone games using Chipmunk, you should check out the Objective-Chipmunk wrapper that we’ve developed for Chipmunk. It integrates with the Objective-C memory model and provides a number of high level APIs that make writing physics based games for the iPhone even easier. While we do charge for Objective-Chipmunk, it will almost certainly save you more time than the small cost to license it. As a bonus, you’ll be helping to ensure that we can afford to continue to work on Chipmunk improvements.
There are two major problems with Chipmunk’s C API. The first is that it lacks operator overloading. Chipmunk defines vector operators as functions instead of allowing you to use operators such as *, +, and -. In practice, it’s usually not a major problem for readability in practice though. The second, and bigger problem is that it’s not possible to mark fields as private in C structure types. Be warned that if you are reading fields from Chipmunk structs that are not documented here, that they might change in the future without a lot of prior warning.
The best way to get support is to visit the Chipmunk Forums. There are plenty of people around using Chipmunk on the just about every platform I’ve ever heard of. If you are working on a commercial project, Howling Moon Software (my company) is available for contracting. We can help with implementing custom Chipmunk behaviors, as well as priority bug fixes and performance tuning.
If you find any bugs in Chipmunk or this document, or have a question or comment about Chipmunk you can contact me at slembcke(at)gmail(dot)com.
Chipmunk is licensed under the MIT license.
Copyright (c) 2007 Scott Lembcke Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This means that you do not have to buy a license or pay to use Chipmunk in commercial projects. (Though we really appreciate donations)
There are 4 basic objects you will use in Chipmunk.
There is often confusion between rigid bodies and their collision shapes in Chipmunk and how they relate to sprites. A sprite would be a visual representation of an object, while a collision shape is an invisible property that defines how objects should collide. Both the sprite’s and the collision shape’s position and rotation are controlled by a rigid body.
Before you do anything else, you must initialize Chipmunk. Otherwise you will crash as soon as the first collision is detected.
cpInitChipmunk(); // That is all
If Chipmunk was not compiled with the NDEBUG flag set, it will also print out the debug mode message and the current version number to stdout.
For many of the structures you will use, Chipmunk uses a more or less standard set of memory management functions. Take the cpSpace struct for example:
cpSpaceAlloc()
– allocates but does not initialize a cpSpace struct.cpSpaceInit(cpSpace *space)
– initializes a cpSpace struct.cpSpaceDestroy(cpSpace *space)
– frees all memory allocated by the cpSpaceInit()
, but does not free the cpSpace struct itself.cpSpaceNew()
– allocates and initializes a cpSpace struct. It calls cpSpaceAlloc()
then cpSpaceInit()
.cpSpaceFree(cpSpace *space)
– calls cpSpaceDestroy()
and then frees the cpSpace struct.While you will probably use the new/free versions exclusively if you are using C/C++, but the alloc/init/destroy functions can be helpful when writing language extensions so that you can more easily work with a garbage collector.
In general, you are responsible for freeing any structs that you allocate. Chipmunk does not have any fancy reference counting or garbage collection built in.
chipmunk_types.h
defines a number of basic types that Chipmunk uses. These can be changed at compile time to better suit your needs:
cpFloat
: Floating point type. Defaults to double
. See below.cpVect
: 2D vector type. cpVect documentationcpBool
: Like every good C library that wants good cross language compatibility, you end up defining your own boolean type. :-\ Defaults to int
.cpDataPointer
: Pointer type defined for callbacks and the user definable data pointer on most Chipmunk structs. Defaults to void*
.cpCollisionType
: Unique identifier for collision shape types. Defaults to unsigned int
.cpGroup
: Unique identifier for collision groups. Defaults to unsigned int
. A CP_NO_GROUP
value is defined that can be used when you don’t want to specify a group.cpLayers
: Type used as the layers bitmask. Defaults to unsigned int
. A CP_ALL_LAYERS
value is defined that has all layer bits set.Note: On the iPhone, cpFloat
is defined as float
and cpVect
is an alias for CGPoint
for performance and compatibility reasons.
First of all, Chipmunk uses double precision floating point numbers throughout it’s calculations by default. This is likely to be faster on most modern desktop processors, and means you have to worry less about floating point round off errors. You can change the floating point type used by Chipmunk when compiling the library. Look in chipmunk_types.h
.
Chipmunk defines a number of aliases for common math functions so that you can choose to use floats or doubles for Chipmunk’s floating point type. In your own code, there probably isn’t a strong reason to use these aliases unless you expect you might want to change Chipmunk’s floating point type later and a 2% performance hit from using the wrong float/double version of math functions will matter.
That said, there are a few functions you will probably find very useful:
cpFloat cpfclamp(cpFloat f, cpFloat min, cpFloat max)
Clamp f
to be between min
and max
.
cpFloat cpflerp(cpFloat f1, cpFloat f2, cpFloat t)
Linearly interpolate between f1
and f2
.
cpFloat cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
Linearly interpolate from f1
towards f2
by no more than d
.
Floating point infinity is defined for you as INFINITY
if your standard math library (cough MSVC cough) doesn’t define it for you.
To represent vectors, Chipmunk defines the cpVect type and a set of inline functions for working with them (cpv, cpvadd, cpvmult, etc). See the API reference for more information..
cpVect
typedef struct cpVect{
cpFloat x, y;
} cpVect
Simply a 2D vector packed into a struct.
#define cpvzero ((cpVect){0.0f, 0.0f})
Constant for the zero vector.
cpVect cpv(const cpFloat x, const cpFloat y)
Convenience constructor for creating new cpVect
structs.
cpBool cpveql(const cpVect v1, const cpVect v2)
Check if two vectors are equal. (Be careful when comparing floating point numbers!)
cpVect cpvadd(const cpVect v1, const cpVect v2)
cpVect cpvsub(const cpVect v1, const cpVect v2)
Add or subtract two vectors.
cpVect cpvneg(const cpVect v)
Negate a vector.
cpVect cpvmult(const cpVect v, const cpFloat s)
Scalar multiplication.
cpFloat cpvdot(const cpVect v1, const cpVect v2)
Vector dot product.
cpFloat cpvcross(const cpVect v1, const cpVect v2)
2D vector cross product analog. The cross product of 2D vectors results in a 3D vector with only a z component. This function returns the magnitude of the z value.
cpVect cpvperp(const cpVect v)
Returns a perpendicular vector. (90 degree rotation)
cpVect cpvrperp(const cpVect v)
Returns a perpendicular vector. (-90 degree rotation)
cpVect cpvproject(const cpVect v1, const cpVect v2)
Returns the vector projection of v1
onto v2
.
cpVect cpvrotate(const cpVect v1, const cpVect v2)
Uses complex multiplication to rotate v1
by v2
. Scaling will occur if v1
is not a unit vector.
cpVect cpvunrotate(const cpVect v1, const cpVect v2)
Inverse of cpvrotate()
.
cpFloat cpvlength(const cpVect v)
Returns the length of v
.
cpFloat cpvlengthsq(const cpVect v)
Returns the squared length of v
. Faster than cpvlength()
when you only need to compare lengths.
cpVect cpvlerp(const cpVect v1, const cpVect v2, const cpFloat t)
Linearly interpolate between v1
and v2
.
cpVect cpvlerpconst(const cpVect v1, const cpVect v2, const cpFloat d)
Linearly interpolate between v1
towards v2
by distance d
.
cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t)
Spherical linearly interpolate between v1
and v2
.
cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a)
Spherical linearly interpolate between v1
towards v2
by no more than angle @a@’ in radians.
cpVect cpvnormalize(const cpVect v)
Returns a normalized copy of v
.
cpVect cpvnormalize_safe(const cpVect v)
Returns a normalized copy of v
or cpvzero
if v
was already cpvzero
. Protects against divide by zero errors.
cpVect cpvclamp(const cpVect v, const cpFloat len)
Clamp v
to length len
.
cpFloat cpvdist(const cpVect v1, const cpVect v2)
Returns the distance between v1
and v2
.
cpFloat cpvdistsq(const cpVect v1, const cpVect v2)
Returns the squared distance between v1
and v2
. Faster than cpvdist()
when you only need to compare distances.
int cpvnear(const cpVect v1, const cpVect v2, const cpFloat dist)
Returns true if the distance between v1
and v2
is less than dist
.
cpVect cpvforangle(const cpFloat a)
Returns the unit length vector for the given angle (in radians).
cpFloat cpvtoangle(const cpVect v)
Returns the angular direction v
is pointing in (in radians).
char *cpvstr(const cpVect v)
Returns a string representation of v
. Intended mostly for debugging purposes and not production use.
NOTE: The string points to a static local and is reset every time the function is called. If you want to print more than one vector you will have to split up your printing onto separate lines.
cpBB
typedef struct cpBB{
cpFloat l, b, r ,t;
} cpBB
Simple bounding box struct. Stored as left, bottom, right, top values.
cpBB cpBBNew(const cpFloat l, const cpFloat b, const cpFloat r, const cpFloat t)
Convenience constructor for cpBB
structs. Like cpv()
this function returns a copy and not a malloced pointer.
int cpBBintersects(const cpBB a, const cpBB b)
Returns true if the bounding boxes intersect.
int cpBBcontainsBB(const cpBB bb, const cpBB other)
Returns true if bb
completely contains other
.
int cpBBcontainsVect(const cpBB bb, const cpVect v)
Returns true if bb
contains v
.
int cpBBmerge(const cpBB a, const cpBB b)
Return the minimal bounding box that contains both a
and b
.
int cpBBexpand(const cpBB bb, const cpVect v)
Return the minimal bounding box that contains both bb
and v
.
cpVect cpBBClampVect(const cpBB bb, const cpVect v)
Returns a copy of v
clamped to the bounding box.
cpVect cpBBWrapVect(const cpBB bb, const cpVect v)
Returns a copy of v
wrapped to the bounding box.
cpBody
typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);
Integration function types. You can write your own integration functions to create your own body behaviors that go beyond applying simply gravity. It’s unlikely that you’ll need to override the position integration function, and if you do you should carefully study how the default function (cpBodyUpdatePosition()
) works. See the planet demo for an example of how to create planetary gravity.
velocity_func
– cpBodyVelocityFunc
: Function pointer called to update the velocity of the body.position_func
– cpBodyPositionFunc
: Function pointer called to update the position of the body.m
– cpFloat
: Mass of the body.i
– cpFloat
: Moment of inertia (MoI or sometimes just moment) of the body. The moment is like the rotational mass of a body. See below for function to help calculate the moment.p
– cpVect
: Position of the body.v
– cpVect
: Velocity of the body.f
– cpVect
: Current force being applied to the body. Note: does not reset automatically as in some physics engines.a
– cpFloat
: Current rotation angle of the body in radians.w
– cpFloat
: Current rotational velocity of the body.t
– cpFloat
: Current torque being applied to the body. Note: does not reset automatically as in some physics engines.rot
– cpVect
: Cached unit length rotation vector.v_limit
– cpFloat
: Maximum speed a body may have after updating it’s velocity.w_limit
– cpFloat
: Maximum rotational speed a body may have after updating it’s velocity.data
– cpDataPointer
: A user definable data pointer. If you set this to point at the game object the shapes is for, then you can access your game object from Chipmunk callbacks.Using the standard single letter names used in physics equations for these values probably wasn’t the best idea in the long run. For me at least, it made things easier as the equations in the code looked more like the written equations I was used to. The getter/setter functions listed below may help save your sanity however.
When changing any of a body’s properties, you should also call cpBodyActivate()
to make sure that it is not stuck sleeping when you’ve changed a property that should make it move again. The cpBodySet*()
functions do this for you automatically.
Note: m
, i
, and a
must be set using setter functions. The body holds on to cached values based on them.
cpBody *cpBodyAlloc(void);
cpBody *cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
cpBody *cpBodyNew(cpFloat m, cpFloat i);
void cpBodyDestroy(cpBody *body);
void cpBodyFree(cpBody *body);
Standard set of Chipmunk memory management functions. m
and i
are the mass and moment of inertia for the body. Guessing the mass for a body is usually fine, but guessing a moment of inertia can lead to a very poor simulation.
Use the following functions to approximate the moment of inertia for your body, adding the results together if you want to use more than one.
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)
Calculate the moment of inertia for a hollow circle, r1
and r2
are the inner and outer diameters in no particular order. (A solid circle has an inner diameter of 0)
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b)
Calculate the moment of inertia for a line segment. The endpoints a
and b
are relative to the body.
cpFloat cpMomentForPoly(cpFloat m, int numVerts, cpVect *verts, cpVect offset)
Calculate the moment of inertia for a solid polygon shape
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height)
Calculate the moment of inertia for a solid box centered on the body.
Because several rigid body values are linked (m
/m_inv
, i
/i_inv
, a
/rot
), don’t set them explicitly. Use the following setter functions instead.
void cpBodySetMass(cpBody *body, cpFloat m);
void cpBodySetMoment(cpBody *body, cpFloat i);
void cpBodySetAngle(cpBody *body, cpFloat a);
While you MUST use the setters in the previous section. You are encouraged to use setters/getters for all properties.
Getters and setters will all be of the form:
cpFloat cpBodyGetMass(cpBody *body)
void cpBodySetMass(cpBody *body, cpFloat mass)
And the full list:
| Name | Type | Read Only? |
|---|---|---|
| Mass | cpFloat | no |
| Moment | cpFloat | no |
| Pos | cpVect | no |
| Vel | cpVect | no |
| Force | cpVect | no |
| Angle | cpFloat | no |
| AngVel | cpFloat | no |
| Torque | cpFloat | no |
| Rot | cpVect | yes |
void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)
Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep. Intended for objects that are moved manually with a custom velocity integration function.
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
Default rigid body velocity integration function. Updates the velocity of the body using Euler integration.
void cpBodyUpdatePosition(cpBody *body, cpFloat dt)
Default rigid body position integration function. Updates the position of the body using Euler integration. Unlike the velocity function, it’s unlikely you’ll want to override this function. If you do, make sure you understand it’s source code as it’s an important part of the collision/joint correction process.
cpVect cpBodyLocal2World(cpBody *body, cpVect v)
Convert from body local coordinates to world space coordinates.
cpVect cpBodyWorld2Local(cpBody *body, cpVect v)
Convert from world space coordinates to body local coordinates.
void cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)
Apply the impulse j
to body
at a relative offset r
from the center of gravity. Both r
and j
are in world coordinates. r
is relative to the position of the body, but not the rotation. Many people get tripped up by this.
void cpBodyResetForces(cpBody *body)
Zero both the forces and torques accumulated on body
.
void cpBodyApplyForce(cpBody *body, cpVect f, cpVect r)
Apply (accumulate) the force f
on body
at a relative offset (important!) r
from the center of gravity.
See Chipmunk Spaces":#cpSpace for more information on Chipmunk’s sleeping feature.
cpBool cpBodyIsSleeping(const cpBody *body)
Returns true if body
is sleeping.
void cpBodySleep(cpBody *body)
Force body
to sleep immediately. Make sure the body is fully set up before you call this. Adding this body or any shapes attached to it, or modifying any of the body’s properties will reactivate it. This is useful if you want an object to be inactive until something hits it such as a pile of boxes you want the player to plow through or a stalactite hanging from a cave ceiling.
void cpBodyActivate(cpBody *body)
Wake body
up so that it starts actively simulating again if it’s sleeping, or reset the idle timer if it’s active.
cpBool cpBodyIsStatic(const cpBody *body)
Returns true if body
is a static body for a space. (cpSpace.staticBody)
cpBool cpBodyIsRogue(const cpBody *body)
Returns true if body
has never been added to a space.
cpShape
There are currently 3 collision shape types:
When creating different types of shapes, you will always be given a cpShape*
pointer back. This is because Chipmunk shapes are meant to be opaque types. Think of the specific collision types such as cpCircleShape
, cpSegmentShape
and cpPolyShape
as private subclasses of cpShape
. You can still read some properties from them using the getter functions, but you are not intended to cast cpShape
pointers to their specific types.
body
– cpBody*
: The rigid body the shape is attached to.bb
– cpBB
: The bounding box of the shape. Only guaranteed to be valid after cpShapeCacheBB()
or cpSpaceStep()
is called. Moving a body that a shape is connected to does not update it’s bounding box.sensor
– cpBool
: A boolean value if this shape is a sensor or not. Sensors only call collision callbacks, and never generate real collisions.e
– cpFloat
: Elasticity of the shape.  However due to inaccuracies in the simulation using 1.0 or greater is not recommended however. See the notes at the end of the section.u
– cpFloat
: Friction coefficient. Chipmunk uses the Coulomb friction model, a value of 0.0 is frictionless. Tables of friction coefficients. See the notes at the end of the section.surface_v
– cpVect
: The surface velocity of the object. Useful for creating conveyor belts or players that move around. This value is only used when calculating friction, not resolving the collision.collision_type
– cpCollisionType
: You can assign types to Chipmunk collision shapes that trigger callbacks when objects of certain types touch. See the callbacks section or an example for more information.group
– cpCollisionGroup
: Shapes in the same non-zero group do not generate collisions. Useful when creating an object out of many shapes that you don’t want to self collide. Defaults to CP_NO_GROUP
.layers
– cpLayers
: Shapes only collide if they are in the same bit-planes. i.e. (a->layers & b->layers) != 0
By default, a shape occupies all bit-planes. Wikipedia has a nice article on bitmasks if you are unfamiliar with how to use them. Defaults to CP_ALL_LAYERS
.data
– cpDataPointer
: A user definable data pointer. If you set this to point at the game object the shapes is for, then you can access your game object from Chipmunk callbacks.Chipmunk has two primary means of ignoring collisions: groups and layers.
Groups are meant to ignore collisions between parts on a complex object. A ragdoll is a good example. When jointing an arm onto the torso, you’ll want them to allow them to overlap. Groups allow you to do exactly that. Shapes that have the same group don’t generate collisions. So by placing all of the shapes in a ragdoll in the same group, you’ll prevent it from colliding against other parts of itself.
Layers allow you to separate collision shapes into mutually exclusive planes. Shapes can be in more than one layer, and shapes only collide with other shapes that are in at least one of the same layers. As a simple example, say shape A is in layer 1, shape B is in layer 2, and shape C is in layer 1 and 2. Shape A and B won’t collide with each other, but shape C will collide with both A and B.
Layers can also be used to set up rule based collisions. Say you have four types of shapes in your game. The player, the enemies, player bullets and enemy bullets. The are that the player should collide with enemies, and bullets shouldn’t collide with the type (player or enemy) that fired them. Making a chart would look like this:
| Player | Enemy | Player Bullet | Enemy Bullet | |
| Player | – | (1) | (2) | |
| Enemy | – | – | (3) | |
| Player Bullet | – | – | – | |
| Enemy Bullet | – | – | – | – |
The ‘-’s are for redundant spots in the chart, and the numbers are spots where types should collide. You can use a layer for rule that you want to define. Then add the layers to each type: The player should be in layers 1 and 2, the enemy should be in layers 1 and 3, the player bullets should be in layer 3, and the enemy bullets should be in layer 2. Treating layers as rules this way, you can define up to 32 rules. The default cpLayers
type is unsigned int
which has a resolution of 32 bits on most systems. Redefine it if you need more to work with.
There is one last way of filtering collisions using collision handlers. See the section on callbacks for more information. While collision handlers can be more flexible, they are also the slowest method. So you try to use groups or layers first.
void cpShapeDestroy(cpShape *shape)
void cpShapeFree(cpShape *shape)
Destroy
and Free
functions are shared by all shape types. Allocation and initialization functions are specific to each shape type. See below.
cpBB cpShapeCacheBB(cpShape *shape)
Updates and returns the bounding box of shape
.
void cpResetShapeIdCounter(void)
Chipmunk keeps a counter so that every new shape is given a unique hash value to be used in the spatial hash. Because this affects the order in which the collisions are found and handled, you can reset the shape counter every time you populate a space with new shapes. If you don’t, there might be (very) slight differences in the simulation.
cpCircleShape *cpCircleShapeAlloc(void)
cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset)
cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset)
body
is the body to attach the circle to, offset
is the offset from the body’s center of gravity in body local coordinates.
cpVect cpCircleShapeGetOffset(cpShape *circleShape)
cpFloat cpCircleShapeGetRadius(cpShape *circleShape)
Getters for circle shape properties. Passing as non-circle shape will throw an assertion.
cpSegmentShape* cpSegmentShapeAlloc(void)
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius)
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius)
body
is the body to attach the segment to, a
and b
are the endpoints, and radius
is the thickness of the segment.
cpVect cpSegmentShapeGetA(cpShape *shape)
cpVect cpSegmentShapeGetA(cpShape *shape)
cpVect cpSegmentShapeGetNormal(cpShape *shape)
cpFloat cpSegmentShapeGetRadius(cpShape *shape)
Getters for segment shape properties. Passing a non-segment shape will throw an assertion.
cpPolyShape *cpPolyShapeAlloc(void)
cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)
cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)
body
is the body to attach the poly to, verts
is an array of cpVect
structs defining a convex hull with a clockwise winding, offset
is the offset from the body’s center of gravity in body local coordinates. An assertion will be thrown the vertexes are not convex or do not have a clockwise winding.
int cpPolyShapeGetNumVerts(cpShape *shape)
cpVect cpPolyShapeGetVert(cpShape *shape, int index)
Getters for poly shape properties. Passing a non-poly shape or an index that does not exist will throw an assertion.
The short answer is that you can’t because the changes would be only picked up as a change to the position of the shape’s surface, but not it’s velocity. The long answer is that you can using the “unsafe” API as long as you realize that doing so will not result in realistic physical behavior. These extra functions are define in a separate header chipmunk_unsafe.h
.
cpSpace
Spaces in Chipmunk are the basic unit of simulation. You add rigid bodies, shapes and constraints to it and then step them forward through time.
Chipmunk uses an iterative solver to figure out the forces between objects in the space. What this means is that it builds a big list of all of the collisions, joints, and other constraints between the bodies and makes several passes over the list considering each one individually. The number of passes it makes is the iteration count, and each iteration makes the solution more accurate. If you use too many iterations, the physics should look nice and solid, but may use up too much CPU time. If you use too few iterations, the simulation may seem mushy or bouncy when the objects should be solid. Setting the number of iterations lets you balance between CPU usage and the accuracy of the physics. Chipmunk’s default of 10 iterations is sufficient for most simple games.
Rogue bodies are bodies that have not been added to the space, but are referenced from shapes or joints. Rogue bodies are a common way of controlling moving elements in Chipmunk such as platforms. As long as the body’s velocity matches the changes to it’s position, there is no problem with doing this. Most games will not need rogue bodies.
In previous versions, Chipmunk also used infinite mass rogue bodies to attach static shapes to. Creating and maintaining your own body for this is no longer necessary as each space has it’s own body for attaching static shapes to. It is also not recommended to do this as it does not work with the sleeping feature. Anything touching or jointed to a rogue body is forbidden from sleeping.
Chipmunk optimizes collision detection against shapes that do not move. Chipmunk doesn’t automatically know if shapes should be static or not. There are two ways to let a Chipmunk space know that a shape is static. The first is to use the space’s static body when creating the shape. When you call cpSpaceAddShape()
on such a shape, it will be added as an optimized static shape. Calling cpSpaceRemoveShape()
will remove the shape. If you want a shape attached to an infinite mass rogue body to be treated as static, you will have to add and remove it’s shape’s using cpSpaceAddStaticShape()
and cpSpaceRemoveStaticShape()
explicitly as Chipmunk has no way to know if the rogue body is meant to be static or not.
Because static shapes aren’t updated automatically, you must let Chipmunk know that it needs to update the static shapes using cpSpaceRehashStatic()
whenever you move a static shape. If you find yourself moving static shapes attached to rogue bodies often, you should add the shapes normally using cpSpaceAddShape()
instead.
New in Chipmunk 5.3 is the ability of spaces to disable entire groups of objects that have stopped moving to save CPU time as well as battery life. In order to use this feature you must do 2 things. The first is that you must use the space’s static body to attach your static shapes to. Because the space controls this body directly, it knows that it won’t move unexpectedly and that means that it is safe to allow things to fall asleep when they are touching it. The second part is much easier, you need to choose a threshold value for cpSpace.sleepTimeThreshold
and optionally cpSpace.idleSpeedThreshold
.
iterations
– int
: Allow you to control the accuracy of the solver. Defaults to 10. See the section on iterations above for an explanation.gravity
– cpVect
: Global gravity applied to the space. Defaults to cpvzero
. Can be overridden on a per body basis by writing custom integration functions.damping
– cpFloat
: Amount of viscous damping to apply to the space. A value of 0.9 means that each body will lose 10% of it’s velocity per second. Defaults to 1. Like gravity
can be overridden on a per body basis.idleSpeedThreshold
– cpFloat
: Speed threshold for a body to be considered idle. The default value of 0 means to let the space guess a good threshold based on gravity.sleepTimeThreshold
– cpFloat
: Time a group of bodies must remain idle in order to fall asleep. The default value of INFINITY
disables the sleeping algorithm.staticBody
– cpBody
: A statically allocated infinite mass body that the space uses to substitute for NULL bodies on shapes and constraints. Set the space->staticBody.data
pointer to something helpful if you want to have some context from within callbacks.cpSpace* cpSpaceAlloc(void)
cpSpace* cpSpaceInit(cpSpace *space)
cpSpace* cpSpaceNew()
void cpSpaceDestroy(cpSpace *space)
void cpSpaceFree(cpSpace *space)
More standard Chipmunk memory functions.
void cpSpaceFreeChildren(cpSpace *space)
This function will free all of the shapes, bodies and joints that have been added to space
. Does not free space
. You will still need to call cpSpaceFree()
on your own. You will probably never use this in a real game, as your gamestate or game controller should manage removing and freeing objects from the space.
void cpSpaceAddShape(cpSpace *space, cpShape *shape)
void cpSpaceAddStaticShape(cpSpace *space, cpShape *shape)
void cpSpaceAddBody(cpSpace *space, cpBody *body)
void cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint)
void cpSpaceRemoveShape(cpSpace *space, cpShape *shape)
void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape)
void cpSpaceRemoveBody(cpSpace *space, cpBody *body)
void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint)
These functions add and remove shapes, bodies and constraints from space
. See the section on Static Shapes above for an explanation of what a static shape is and how it differs from a normal shape. Also, you cannot call the any of these functions from within a callback other than a post-step callback (which is different than a post-solve callback!). Attempting to add or remove objects from the space while cpSpaceStep()
is still executing will throw an assertion. See the callbacks section for more information.
Chipmunk uses a spatial hash to accelerate it’s collision detection. While it’s not necessary to interact with the hash directly. The current API does expose some of this at the space level to allow you to tune it’s performance.
void cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count)
void cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count)
The spatial hash data structures used by Chipmunk’s collision detection are fairly size sensitive. dim
is the size of the hash cells. Setting dim
to the average collision shape size is likely to give the best performance. Setting dim
too small will cause the shape to be inserted into many cells, setting it too low will cause too many objects into the same hash slot.
count
is the suggested minimum number of cells in the hash table. If there are too few cells, the spatial hash will return many false positives. Too many cells will be hard on the cache and waste memory. the Setting count
to ~10x the number of objects in the space is probably a good starting point. Tune from there if necessary. By default, dim
is 100.0, and count
is 1000. The new demo program has a visualizer for the static hash. You can use this to get a feel for how to size things up against the spatial hash.
Using the spatial has visualization in the demo program you can see what I mean. The grey squares represent cells in the spatial hash. The darker the cell, the more objects have been mapped into that cell. A good dim
size is when your objects fit nicely into the grid:
Notice the light grey meaning that each cell doesn’t have too many objects mapped onto it.
When you use too small a size, Chipmunk has to insert each object into a lot of cells. This can get expensive.
Notice that the grey cells are very small compared to the collision shapes.
When you use too big of a size, a lot of shapes will fit into each cell. Each shape has to be checked against every other shape in the cell, so this makes for a lot of unnecessary collision checks.
Notice the dark grey cells meaning that many objects are mapped onto them.
void cpSpaceRehashStatic(cpSpace *space)
Rehashes the shapes in the static spatial hash. You must call this if you move any static shapes or Chipmunk won’t update their collision detection data.
void cpSpaceStep(cpSpace *space, cpFloat dt)
Update the space for the given time step. Using a fixed time step is highly recommended. Doing so will increase the efficiency of the contact persistence, requiring an order of magnitude fewer iterations and CPU usage.
count
argument to cpHashResizeStaticHash()
than to cpSpaceResizeActiveHash()
. Doing so will use more memory but can improve performance if you have a lot of static shapes.cpConstraint
A constraint is something that describes how two bodies interact with each other. (how they constrain each other) Constraints can be simple joints that allow bodies to pivot around each other like the bones in your body, or they can be more abstract like the gear joint or motors.
Constraints in Chipmunk are all velocity based constraints. This means that they act primarily by synchronizing the velocity of two bodies. A pivot joint holds two anchor points on two separate bodies together by defining equations that say that the velocity of the anchor points must be the same and calculating impulses to apply to the bodies to try and keep it that way. A constraint takes a velocity as it’s primary input and produces a velocity change as it’s output. Some constraints, (joints in particular) apply velocity changes to correct differences in positions. More about this in the next section.
A spring connected between two bodies is not a constraint. It’s very constraint-like as it creates forces that affect the velocities of the two bodies, but a spring takes distances as input and produces forces as it’s output. If a spring is not a constraint, then why do I have two varieties of spring constraints you ask? The reason is because they are damped springs. The damping associated with the spring is a true constraint that creates velocity changes based on the relative velocities of the two bodies it links. As it is convenient to put a damper and a spring together most of the time, I figured I might as well just apply the spring force as part of the constraint instead of having a damper constraint and having the user calculate and apply their own spring forces separately.
a
– cpBody*
: The first body that the constraint acts on.b
– cpBody*
: The second body that the constraint acts on.maxForce
– cpFloat
: is the maximum force that the constraint can use to act on the two bodies. Defaults to INFINITY.biasCoef
– cpFloat
: is the percentage of error corrected each step of the space. (Can cause issues if you don’t use a constant time step) Defaults to 0.1.maxBias
– cpFloat
: is the maximum speed at which the constraint can apply error correction. Defaults to INFINITY.data
– cpDataPointer
: A user definable data pointer. If you set this to point at the game object the shapes is for, then you can access your game object from Chipmunk callbacks.To access properties of specific joint types, use the getter and setter functions provided (ex: cpPinJointGetAnchr1()
). See the lists of properties for more information.
Joints in Chipmunk are not perfect. A pin joint can’t maintain the exact correct distance between it’s anchor points, nor can a pivot joint hold it’s anchor points completely together. Instead, they are designed to deal with this by correcting themselves over time. In Chipmunk 5, you have a fair amount of extra control over how joints correct themselves and can even use this ability to create physical effects that allow you to use joints in unique ways:
There are three public fields of cpConstraint structs that control the error correction, maxForce
, maxBias
, and biasCoef
. maxForce
is pretty self explanatory, a joint or constraint will not be able to use more than this amount of force in order to function. If it needs more force to be able to hold itself together, it will fall apart. maxBias
is the maximum speed at which error correction can be applied. If you change a property on a joint so that the joint will have to correct itself, it normally does so very quickly. By setting a maxSpeed you can make the joint work like a servo, correcting itself at a constant rate over a longer period of time. Lastly, biasCoef
is the percentage of error corrected every step before clamping to a maximum speed. You can use this to make joints correct themselves smoothly instead of at a constant speed, but is probably the least useful of the three properties by far.
Neither constraints or collision shapes have any knowledge of the other. When connecting joints to a body the anchor points don’t need to be inside of any shapes attached to the body and it often makes sense that they shouldn’t. Also, adding a constraint between two bodies doesn’t prevent their collision shapes from colliding. In fact, this is the primary reason that the collision group property exists.
void cpConstraintDestroy(cpConstraint *constraint)
void cpConstraintFree(cpConstraint *constraint)
Destroy
and Free
functions are shared by all joint types. Allocation and initialization functions are specific to each joint type.
cpFloat cpConstraintGetImpulse(cpConstraint *constraint)
Get the most recent impulse that constraint
applied. To convert this to a force, divide by the timestep passed to cpSpaceStep()
.
cpPinJoint *cpPinJointAlloc(void)
cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
cpConstraint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
a
and b
are the two bodies to connect, and anchr1
and anchr2
are the anchor points on those bodies. The distance between the two anchor points is measured when the joint is created. If you want to set a specific distance, use the setter function to override it.
Properties List:
| Name | Type |
|---|---|
| Anchr1 | cpVect |
| Anchr2 | cpVect |
| Dist | cpFloat |
cpSlideJoint *cpSlideJointAlloc(void)
cpSlideJoint *cpSlideJointInit(
cpSlideJoint *joint, cpBody *a, cpBody *b,
cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max
)
cpConstraint *cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)
a
and b
are the two bodies to connect, anchr1
and anchr2
are the anchor points on those bodies, and min
and max
define the allowed distances of the anchor points.
Properties List:
| Name | Type |
|---|---|
| Anchr1 | cpVect |
| Anchr2 | cpVect |
| Min | cpFloat |
| Max | cpFloat |
cpPivotJoint *cpPivotJointAlloc(void)
cpPivotJoint *cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect pivot)
cpConstraint *cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot)
cpConstraint *cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
a
and b
are the two bodies to connect, and pivot
is the point in world coordinates of the pivot. Because the pivot location is given in world coordinates, you must have the bodies moved into the correct positions already. Alternatively you can specify the joint based on a pair of anchor points, but make sure you have the bodies in the right place as the joint will fix itself as soon as you start simulating the space.
Properties List:
| Name | Type |
|---|---|
| Anchr1 | cpVect |
| Anchr2 | cpVect |
cpGrooveJoint *cpGrooveJointAlloc(void)
cpGrooveJoint *cpGrooveJointInit(
cpGrooveJoint *joint, cpBody *a, cpBody *b,
cpVect groove_a, cpVect groove_b, cpVect anchr2
)
cpConstraint *cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)
The groove goes from groov_a
to groove_b
on body a
, and the pivot is attached to anchr2
on body b
. All coordinates are body local.
Properties List:
| Name | Type |
|---|---|
| Anchr2 | cpVect |
| GrooveA | cpVect |
| GrooveB | cpVect |
cpDampedSpring *cpDampedSpringAlloc(void)
cpDampedSpring *cpDampedSpringInit(
cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2,
cpFloat restLength, cpFloat stiffness, cpFloat damping
)
cpConstraint *cpDampedSpringNew(
cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2,
cpFloat restLength, cpFloat stiffness, cpFloat damping
)
Defined much like a slide joint. restLength
is the distance the spring wants to be, stiffness
is the spring constant (Young’s modulus), and damping
is how soft to make the damping of the spring.
Properties List:
| Name | Type |
|---|---|
| Anchr1 | cpVect |
| Anchr2 | cpVect |
| RestLength | cpFloat |
| Stiffness | cpFloat |
| Damping | cpFloat |
cpDampedRotarySpring *cpDampedRotarySpringAlloc(void)
cpDampedRotarySpring *cpDampedRotarySpringInit(
cpDampedRotarySpring *joint, cpBody *a, cpBody *b,
cpFloat restAngle, cpFloat stiffness, cpFloat damping
)
cpConstraint *cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping)
Like a damped spring, but works in an angular fashion. restAngle
is the relative angle in radians that the bodies want to have, stiffness
and damping
work basically the same as on a damped spring.
Properties List:
| Name | Type |
|---|---|
| RestAngle | cpFloat |
| Stiffness | cpFloat |
| Damping | cpFloat |
cpRotaryLimitJoint *cpRotaryLimitJointAlloc(void)
cpRotaryLimitJoint *cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max)
cpConstraint *cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max)
Constrains the relative rotations of two bodies. min
and max
are the angular limits in radians. It is implemented so that it’s possible to for the range to be greater than a full revolution.
Properties List:
| Name | Type |
|---|---|
| Min | cpFloat |
| Max | cpFloat |
cpRatchetJoint *cpRatchetJointAlloc(void);
cpRatchetJoint *cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
cpConstraint *cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
Works like a socket wrench. ratchet
is the distance between “clicks”, phase
is the initial offset to use when deciding where the ratchet angles are.
Properties List:
| Name | Type |
|---|---|
| Angle | cpFloat |
| Phase | cpFloat |
| Ratchet | cpFloat |
cpGearJoint *cpGearJointAlloc(void);
cpGearJoint *cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
cpConstraint *cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
Keeps the angular velocity ratio of a pair of bodies constant. ratio
is always measured in absolute terms. It is currently not possible to set the ratio in relation to a third body’s angular velocity. phase
is the initial angular offset of the two bodies.
Properties List:
| Name | Type |
|---|---|
| Phase | cpFloat |
| Ratio | cpFloat |
cpSimpleMotor *cpSimpleMotorAlloc(void);
cpSimpleMotor *cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
cpConstraint *cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);
Keeps the relative angular velocity of a pair of bodies constant. rate
is the desired relative angular velocity. You will usually want to set an force (torque) maximum for motors as otherwise they will be able to apply a nearly infinite torque to keep the bodies moving.
Properties List:
| Name | Type |
|---|---|
| Rate | cpFloat |
In order to make collision detection in Chipmunk as fast as possible, the process is broken down into several stages. While I’ve tried to keep it conceptually simple, the implementation can be a bit daunting. Fortunately as a user of the library, you don’t need to understand everything about how it works. If you are trying to squeeze every ounce of performance out of Chipmunk, understanding this section is crucial.
Chipmunk contains a few global variables that control how collisions are solved. They can’t be set on a per space basis, but most games wont need to change them at all.
extern cpFloat cp_bias_coef
Because Chipmunk does not perform swept collisions, shapes may overlap. Each time you call cpSpaceStep()
Chipmunk fixes a percentage of the overlap to push the shapes apart. By default, this value is set to 0.1. With this setting, after 15 steps the overlap will be reduced to 20%, after 30 it will be reduced to 4%. This is usually satisfactory for most games. Setting cp_bias_coef to 1.0 is not recommended as it will reduce the stability of stacked objects.
extern cpFloat cp_collision_slop
Chipmunk’s impulse solver works by caching the last solution as it is likely to be very similar to the current one. In order to help keep objects touching, Chipmunk allows objects to overlap a small amount. By default this value is 0.1. If you are using pixel coordinates you won’t even notice. If using a different scale, adjust the value to be as high as possible without creating any unwanted visual overlap.
extern cpTimestamp cp_contact_persistence
This is how many steps the space should remember old contact solutions. The default value is 3 and it’s unlikely that you’ll need to change it.
Chipmunk uses a spatial hash for its broad phase culling. Spatial hashes are very efficient for a scene made up of consistently sized objects. It basically works by taking the axis aligned bounding boxes for all the objects in the scene, mapping them onto an infinite sized grid, then mapping those grid cells onto a finite sized hash table. This way, you only have to check collisions between objects in the same hash table cells, and mapping the objects onto the grid can be done fairly quickly. Objects in the same hash table cells tend to be very close together, and therefore more likely to be colliding. The downside is that in order to get the best performance out of a spatial hash, you have to tune the size of the grid cells and the size of the hash table so you don’t get too many false positives. For more information about tuning the hash see the cpSpace section.
Things to keep in mind:
For more information on spatial hashing in general, Optimized Spatial Hashing for Collision Detection of Deformable Objects is a good paper that covers all the basics.
After the spatial hash figures out pairs of shapes that are likely to be near each other, it passes them back to the space to perform some additional filtering on the pairs. If the pairs pass all the filters, then Chipmunk will test if the shapes are actually overlapping. If the shape to shape collision check passes, then the collision handler callbacks are called. These tests are much faster to try than the shape to shape collision checks, so use these if you can to reject collisions early instead of rejecting them from callbacks if you can.
The most expensive test that you can do to see if shapes should collide is to actually check based on their geometry. Circle to circle and circle to line collisions are pretty quick. Poly to poly collisions get more expensive as the number of vertexes increases. Simpler shapes make for faster collisions (and more importantly fewer collision points for the solver to run).
After checking if two shapes overlap Chipmunk will look to see if you have defined a collision handler for the collision types of the shapes.  The return value of the begin and preSolve callback determines whether or not the colliding pair of shapes is discarded or not. Returning true will keep the pair, false will discard it. If you don’t define a handler for the given collision_types, Chipmunk will call the space’s default handler, which by default is defined to simply accept all collisions.
While using callbacks to filter collisions is the most flexible way, keep in mind that by the time your callback is called all of the most expensive collision detection has already been done. For simulations with a lot of colliding objects each frame, the time spent finding collisions is small compared to the time spent solving the physics for them so it may not be a big deal. Still, use layers or groups first if you can.
A physics library without any events or feedback would not be very useful for games. How would you know when the player bumped into an enemy so that you could take some health points away? How would you know how hard the car hit something so you don’t play a loud crash noise when a pebble hits it? What if you need to decide if a collision should be ignored based on specific conditions, like implementing one way platforms? Chipmunk has a number of powerful callback systems that you can plug into to accomplish all of that.
A collision handler is a set of 4 function callbacks for the different collision events that Chipmunk recognizes. The event types are:
Collision callbacks are closely associated with cpArbiter structs. You should familiarize yourself with those as well.
Note: Shapes tagged as sensors (cpShape.sensor == true
) never generate collisions that get processed so collisions between sensors shapes and other shapes will never call the post-solve callback. They still generate begin, and separate callbacks, and the pre solve callback is also called every frame even though there is no real collision.
typedef int (*cpCollisionBeginFunc)(cpArbiter *arb, struct cpSpace *space, void *data)
typedef int (*cpCollisionPreSolveFunc)(cpArbiter *arb, cpSpace *space, void *data)
typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, cpSpace *space, void *data)
typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, cpSpace *space, void *data)
Collision handler function types. While all of them take an arbiter, space, and a user data pointer, only the begin and pre-solve callbacks return a value. See above for more information.
void cpSpaceAddCollisionHandler(
cpSpace *space,
cpCollisionType a, cpCollisionType b,
cpCollisionBeginFunc begin,
cpCollisionPreSolveFunc preSolve,
cpCollisionPostSolveFunc postSolve,
cpCollisionSeparateFunc separate,
void *data
)
Add a collision handler for given collision type pair. Whenever a shapes with collision type (cpShape.collision_type
) a
and collision type b
collide, these callbacks will be used to process the collision. data
is a user definable context pointer that is passed to each of the callbacks. NULL can be provided for callbacks you do not wish to implement, however Chipmunk will call it’s own default versions for these and not the default ones you’ve set up for the space. If you need to fall back on the space’s default callbacks, you’ll have to provide them individually to each handler definition.
void cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
Remove a collision handler for a given collision type pair.
void cpSpaceSetDefaultCollisionHandler(
cpSpace *space,
cpCollisionType a, cpCollisionType b,
cpCollisionBeginFunc begin,
cpCollisionPreSolveFunc preSolve,
cpCollisionPostSolveFunc postSolve,
cpCollisionSeparateFunc separate,
void *data
)
Register a default collision handler to be used when no specific collision handler is found. The space is given a default handler when created that returns true for all collisions in begin()
and preSolve()
and does nothing in the postSolve()
and separate()
callbacks.
Post-step callbacks are the one place where you can break the rules about adding or removing objects from within a callback. In fact, their primary function is to help you safely remove objects from the space that you wanted to disable or destroy in a collision callback.
Post step callbacks are registered as a function and a pointer that is used as a key. You can only register one post step callback per key. This prevents you from accidentally removing an object more than once. For instance, say that you get a collision callback between a bullet and object A. You want to destroy both the bullet and object A, so you register a post-step callback to safely remove them from your game. Then you get a second collision callback between the bullet and object B. You register a post-step callback to remove object B, and a second post-step callback to remove the bullet. Because you can only register one callback per key, the post-step callback for the bullet will only be called once and you can’t accidentally try to remove it twice.
typedef void (*cpPostStepFunc)(cpSpace *space, void *obj, void *data)
Function type used for post step callbacks. space
is the space the callback was registered on, obj
is the pointer value you supplied as the key, and data
is a user definable pointer you can use to pass in as a context value.
void cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *obj, void *data)
Add func
to be called before cpSpaceStep()
returns. obj
and data
will be passed to your function. Only the last callback registered for any unique value of obj
will be recorded. You can add post-step callbacks from outside of other callback functions, but they won’t be called until cpSpaceStep()
is called again.
See the callback examples for more information.
cpArbiter
First of all, why are they called arbiters? The short answer is that Box2D called them that way back in 2006 when I was looking at the source for it’s solver. An arbiter is like a judge, a person that has authority to settle disputes between two people. It was a fun, fitting name and was shorter to type than CollisionPair which I had been using. :p
Originally arbiters were going to be an internal data type that Chipmunk used that wouldn’t ever be sent to outside code. In Chipmunk 4.x and earlier, only a single callback hook was provided for handling collision events. It was triggered every step that to shapes were touching. This made it non-trivial to track when objects started and stopped touching as the user would have to record and process this themselves. Many people, including myself, wanted to get collision begin/separate events and eventually I realized that information was already being stored in the arbiter cache that the Chipmunk maintains. With some changes to the collision callback API, that information is now exposed to the user. Internally, arbiters are used primarily for solving collision impulses. To external users, you can simply think of them as a weird type used in collision callbacks.
You should never need to create an arbiter, nor will you ever need to free one as they are handled by the space. More importantly, because they are managed by the space you should never store a reference to an arbiter as you don’t know when they will be destroyed. Use them within the callback where they are given to you and then forget about them or copy out the information you need from them.
void cpArbiterGetShapes(cpArbiter *arb, cpShape **a, cpShape **b)
#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
Get the shapes in the order that they were defined in the collision handler associated with this arbiter. If you defined the handler as cpSpaceAddCollisionHandler(space, 1, 2, ...)
, you you will find that a->collision_type == 1
and b->collision_type == 2
. The convenience macro defines and initializes the two shape variables for you. example
int cpArbiterIsFirstContact(cpArbiter *arb)
Returns true if this is the first step that the shapes touched. You can use this from preSolve()
and postSolve()
callbacks to know if a collision between two shapes is new without needing to flag a boolean in your begin callback.
cpVect cpArbiterGetNormal(cpArbiter *arb, int i)
Returns the collision normal for the i’th contact point, flipping it if necessary. Note: Currently due to how Chipmunk’s collision detection is implemented, the collision normals will be the same for all collision points. You can simply do cpArbiterGetNormal(arb, 0)
and not have to check each contact point. Note: calling this function from the separate()
callback is undefined.
cpVect cpArbiterGetPoint(cpArbiter *arb, int i)
Returns the position of the i’th collision point. Note: calling this function from the separate()
callback is undefined.
cpVect cpArbiterTotalImpulse(cpArbiter *arb);
cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);
Returns the impulse that was applied this step to resolve the collision. These functions should only be called from a postStep()
callback, otherwise the result is undefined. Note: If you are using the deprecated elastic iterations setting on your space, it will cause you to get incorrect results. Elastic iterations should no longer be needed, and you should be able to safely turn them off.
It’s unlikely that you’ll need to interact with a cpArbiter
struct directly as the collision helper functions should provide most functionality that people will need. One exception is the e
, and u
fields. By default, Chipmunk multiplies the friction and elasticity values of to shapes together to determine what values to use when solving the collision. This mostly works, but in many cases is simply not flexible enough. If you are running into problems with that, you can change the values calculated for e
and u
in a preSolve callback. This is likely to change in the next major version of Chipmunk.
numContacts
– int
: Number of contact points for this collision.e
– cpFloat
: Calculated amount of elasticity to apply for this collision. Can be overriden from a preSolve()
callback.u
– cpFloat
: Calculated amount of friction to apply for this collision. Can be overriden from a preSolve()
callback.surface_v
– cpVect
: Calculated amount of surface velocity to apply for this collision. Can be overriden from a preSolve()
callback. (Very likely to change in the next major version of Chipmunk).Chipmunk spaces currently support three kinds of spatial queries, point, segment and bounding box. Any type can be done efficiently against an entire space, or against individual shapes. All types of queries take a collision group and layer that are used to filter matches out using the same rules used for filtering collisions between shapes. See cpShape for more information. If you don’t want to filter out any matches, use CP_ALL_LAYERS
for the layers and CP_NO_GROUP
as the group.
Point queries are useful for things like mouse picking and simple sensors.
cpBool cpShapePointQuery(cpShape *shape, cpVect p)
Check if the given point lies within the shape.
typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);
void cpSpacePointQuery(
cpSpace *space, cpVect point,
cpLayers layers, cpGroup group,
cpSpacePointQueryFunc func, void *data
)
Query space
at point
filtering out matches with the given layers
and group
. func
is called for each shape found along with the data
argument passed to cpSpacePointQuery()
.
cpShape *cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group)
Query space
at point
and return the first shape found matching the given layers
and group
. Returns NULL
if no shape was found.
Segment queries are like ray casting, but because Chipmunk uses a spatial hash to process collisions, it cannot process infinitely long queries like a ray. In practice this is still very fast and you don’t need to worry too much about the performance as long as you aren’t using extremely long segments for your queries.
typedef struct cpSegmentQueryInfo{
struct cpShape *shape; // shape that was hit, NULL if no collision
cpFloat t; // Distance along query segment, will always be in the range "1":0,.
cpVect n; // normal of hit surface
} cpSegmentQueryInfo;
Segment queries return more information than just a simple yes or no, they also return where a shape was hit and it’s surface normal at the hit point. t
is the percentage between the query start and end points. If you need the hit point in world space or the absolute distance from start, see the segment query helper functions farther down.
cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)
Check if the line segment from a
to b
intersects the shape. info
must be a valid pointer to a cpSegmentQueryInfo
structure which will be initialized with the raycast info.
typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpFloat t, cpVect n, void *data)
cpBool cpSpaceSegmentQuery(
cpSpace *space, cpVect start, cpVect end,
cpLayers layers, cpGroup group,
cpSpaceSegmentQueryFunc func, void *data
)
Query space
along the line segment from start
to end
filtering out matches with the given layers
and group
. func
is called with the normalized distance along the line and surface normal for each shape found along with the data
argument passed to cpSpacePointQuery()
.
cpShape *cpSpaceSegmentQueryFirst(
cpSpace *space, cpVect start, cpVect end,
cpLayers layers, cpGroup group,
cpSegmentQueryInfo *info
)
Query space
along the line segment from start
to end
filtering out matches with the given layers
and group
. Only the first shape encountered is returned and the search is short circuited. Returns NULL
if no shape was found. The info struct pointed to by info
will be initialized with the raycast info unless info
is NULL.
cpVect cpSegmentQueryHitPoint(cpVect start, cpVect end, cpSegmentQueryInfo info)
Return the hit point in world coordinates where the segment first intersected with the shape.
cpFloat cpSegmentQueryHitDist(cpVect start, cpVect end, cpSegmentQueryInfo info)
Return the absolute distance where the segment first hit the shape.
See the query examples for more information.


{% load staticfiles %}
Nombre: Puntos: 0 Velocidad: 3/8
Touch events are now supported! Play on iOS and Android: Swipe anywhere to move, tap to rotate (Can also tap while swiping to rotate). Swipe down to drop.
Touch Sensitivity: 1


Introducing “Skunk”. A responsive one page website, designed & developed by Salam Jamiu, exclusively for CODEGEES.
Join Now Learn moreEasily customise Skunk to suit your start up, portfolio or product.
Designed with modern trends and techniques in mind, Skunk will help your product stand out in an already saturated market.
Built using the latest web technologies like html5, css3, and jQuery, rest assured Skunk will look smashing on every device under the sun.
Present your product, start up, or portfolio in a beautifully modern way. Turn your visitors in to clients.
Skunk is universal and will look smashing on any device.
Skunk takes advantage of common design patterns, allowing for a seamless experience for users of all levels.
Download and re-use the Skunk open source code for any other project you like.
Easily change/switch/swap every placeholder inside every image on Skunk with the included BootStrap files. You’ll have this template customised to suit your business in no time!
Nam vehicula malesuada lectus, interdum fringilla nibh. Duis aliquam vitae metus a pharetra. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum augue quis augue ornare, eget faucibus felis pharetra. Proin condimentum et leo quis fringilla.
What's BootStrap?Change/swap/edit every aspect of Skunk before you hit development with the included BootStrap file.
Join now!Minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Grab your copy today, exclusively from CODEGEES


Check Here!
Physics
Chemistry
Mathematics
Subjects
C-Programming
Control System
Digital Communication
© 2019 E-learning. All rights reserved | Design by AppleTech Solution


The sexy people behind the magic of Adulting 101
Gina Pultorak
Is originally from Philly, and proud! Gina worked in Nonprofits and learning/development. She loves music and the city of Seattle.
Lyndsey Thomas
Lyndsey is basically a giant sissybaby, considering the fact that she loves haunted houses so much. Eating cheese and drinking wine are her favorite things.
Sarah Fisher
Sarah is a nature nerd who is still confused by the fact that she choose to study tech. Her whole world revolves around her family and her dogs (and everyone else's dogs, too).
Jonathan Kimball
Was born in Vancouver B.C., and raised in northern Maine. Has lived in Seattle 20 years, and creates electronic music using computers!


“We must not oppose for the sake of opposing” – New SPP chief echoes WP’s approach to politics
- Advertisement -
In a press statement released on Thursday (Nov 14), newly minted Singapore People’s Party (SPP) chief Steve Chia has said the opposition must not exist for the sake of opposing to be a constructive force, echoing recent remarks made by the leader of the Workers’ Party.
In a Facebook post published on Wednesday (Nov 13), Workers’ Party (WP) secretary-general Pritam Singh said the WP believes the opposition plays a “check and balance role” and that his party aims to help build a better Singapore for all Singaporeans, not to destroy its political opponents.
Laying out his party’s approach to politics, Mr Singh said: “The Workers’ Party fundamentally believes that an opposition plays an important check and balance role and is an integral part of our parliamentary democracy, no matter which party is in Government and whoever is represented by the opposition.
“To that end, our objective is not the destruction of our political opponents. It is beyond the horizon – a better Singapore for all Singaporeans. The way the WP approaches opposition politics is a reflection of this. We believe this approach is one that Singaporeans, even PAP supporters (who we also must level with and persuade rationally) endorse – a loyal opposition.”
- Advertisement -
Mr Singh also said that opposition unity remains a challenge since different parties have different ideologies and approaches. Referring to his predecessor Low Thia Khiang’s words in 2013 that opposition unity in Singapore is difficult, if not impossible, Mr Singh said:
“…not every opposition party believes the same thing. As a small political player in our landscape, the WP must get its political purpose right. To a large extent, this explains why opposition unity – notwithstanding friendly discussions and relationships amongst opposition members – remains a real challenge.”
In his second press statement since he was elected party leader, the new SPP secretary-general Steve Chia echoed Mr Singh’s views, asserting that the SPP too, believes in playing a check and balance role and that opposition unity can only be achieved if the various parties share the same values and vision. He said:
“One of the key roles of the Opposition is to act as a check and balance on the policies of the Government, by speaking up for Singaporeans. This is to ensure that Singapore and Singaporeans are always at the heart of the Government’s policies. Where possible, the Opposition should also propose alternative policies.
“It is vital that the opposition are loyal to Singapore and fellow Singaporeans. As Mr Chiam had said in Parliament, “…above all, in the Opposition, we must be good and patriotic Singaporeans.”
“In order to be a credible, competent and constructive force, we must not oppose for the sake of opposing. As I had said in the 10th session of Parliament, “if Government policies are good, what is there to oppose. But if it is not, we will be the first to oppose it.”
“We believe in the need for an honest, constructive and harmonious approach to politics. Thus, being a loyal opposition for Singapore and Singaporeans is a key value that SPP has always stood by.
“While we value opposition unity, we also understand that the opposition can be united only if we share similar values, practices and have the same vision for Singapore.”
Mr Chia – a former Non-Constituency Member of Parliament (NCMP) – took over the reins of the SPP from veteran opposition politician Chiam See Tong earlier this month when he was elected secretary-general by party cadres.
84-year-old Mr Chiam decided not to contest the party’s latest internal election for the first time in 23 years, effectively bringing his 40-year political career to an end.
- Advertisement -


Features of Making Payment on Voluntary Basis (Form GST DRC-03) on GST Portal
11/10/2019
Making Voluntary Payment on GST Portal: A facility is given to taxpayers to make payment on voluntary basis, through Form GST DRC-03 (refer Rule 142(2) or 142(3) of the CGST Rules, 2017). Login into GST Portal and navigate to Services > User Services > My Applications and Select the Intimation of Voluntary Payment - DRC – 03, from the Application Type drop-down list.
When to make Payment Voluntary Payment: Payment can be voluntarily made by taxpayer for a self-ascertained liability or in response to the show cause notice (SCN) raised by the tax authorities, u/s 73 or 74 of the CGST Act, 2017, within 30 days of issuance of SCN or even before issuance of the SCN.
Partial Payment not allowed: GST Portal does not allow for making partial payments of the amount stated in the SCN.
Cause of Payment: Payments through Form GST DRC-03 can be made for any causes like Audit, Investigation, Voluntary Payment, SCN, Annual Return, Reconciliation Statement or Others.
Saving Draft DRC 03 Application: Draft of Application for intimation of voluntary payment can be saved for a maximum period of 15 days. If the same is not filed within 15 days, the saved draft will be purged. To view the saved application, navigate to Services > User Services > My Saved Applications option.
Using Payment Reference Number: If payment has been made and payment reference number (PRN) has been generated, but application in Form GST DRC-03 has not been filed, then in such cases, application available in ‘My Saved Applications’ need to be selected and using PRN already generated, it may be filed. However, if a period of fifteen days has elapsed, then, details in Form need to be filled up again. PRN generated already can be used for filing the application.
Filing Form GST DRC 03: Taxpayers are required to file Form GST DRC-03 using DSC or EVC, as the case may be, after making payment. The status will change to “Pending for approval by Tax officer”. However, it may be noted that, no approval of tax officer is needed on earlier application, while making another voluntary payment using FORM GST DRC 03.
Acknowledgment by Tax Official: Upon filing of Form GST DRC-03, the tax officer will issue an Acknowledgement in Form GST DRC-04(Acknowledgement of Acceptance of voluntary payment). There is no bar on making another payment on voluntary basis by a taxpayer, pending issuance of acknowledgement by the tax officer.
Thanking you,
Team GSTN


Make Game Design Great Again
- High Concept:
Get most amount of money.
- Theme:
SideScroller.
- Mandated Variety:
SideScroller, Predetermined game layout.
- Player Experience Goals:
Laugh at our president.
- Gameplay:
Player is constantly running. Player can jump and duck.
- Prototype Goal:
Trying out Tile Map Editor.
- Features:
Funny Graphics. :)
- Setting/Premise:
Trump is sent to an open field where he must gather money in order to become president of the United Nations. He must do so while avoiding taxes as taxes are his weaksness.
- Story:
Future iterations may containt press people coming to him and he will have a catch phrase.
- Target Audience:
American people.
- Play Time:
30 seconds.
- Strategies:
Player must time jumps as to avoid falling into pits and taxes.
- Prototype Assets:
- Prototype Closest Other Game:
Followed this example: https://github.com/fariazz/phaser-sidescroller/tree/master/js


About
This website is part of the course websoft XXX. Update so that the link goes to the course page on HKR website.
Provide some insights on the course this far or exaplin a bit more about this website?
Add a representiv image for the course, at your own liking.
Provide an url to the course repo on GitHub.


All functions exported by gesundheit are available as globals below.
Returning a Gesundheit object (such as a query or AST node) will cause it to be compiled and the resulting SQL + parameters displayed


Are you sure you want to install the database structure?
The installation has succeeded.
back to menu